home *** CD-ROM | disk | FTP | other *** search
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # README
- # games
- # src
- # This archive created: Wed Feb 21 22:52:27 1990
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'README'
- then
- echo shar: "will not over-write existing file 'README'"
- else
- cat << \SHAR_EOF > 'README'
- To print documentation :-
- mmx -t -gc $GO/src/go.mmx
- or if there is no memorandum macro formatter :-
- lp $GO/src/go.mmx.out
- SHAR_EOF
- fi
- if test ! -d 'games'
- then
- mkdir 'games'
- fi
- cd 'games'
- if test -f 'basics.go'
- then
- echo shar: "will not over-write existing file 'basics.go'"
- else
- cat << \SHAR_EOF > 'basics.go'
- #"basics.go" - press space now and everytime you wish to see more lines
- !numbers
- !lastmove
- 9 0|
- #Go can can be played on any size board though 9x9, 13x13 and 19x19
- #are more usual. For the moment we shall use a 9x9 board.
- #Play starts with the board empty.
- #A move consists of placing a piece (called a 'stone') on a vacant point, any
- #vacant point can be chosen, subject to a prohibition described later.
- #Players move alternately, Black moving first eg at D3
- d3 |
- # ... then white at C7
- C7 |
- # and black at C5
- C5 |
- # and so on.
- # |
- #Stones once played are not moved about, unless they are captured, in which
- #case they are removed from the board.
- #Thus the board gradually fills up with stones during play.
- # |
- #The basic object of the game is to surround vacant areas of the board.
- #the player who controls more territory, consisting of vacant points, at
- #the end of the game is the winner.
- #For example here is a game that has been completed ...
-
- 9 0 |
- B9 |
- pass |
- B8 |
- pass |
- C8 |
- pass |
- C7 |
- pass |
- D7 |
- pass |
- D6 |
- pass |
- D5 |
- pass |
- E5 |
- pass |
- F5 |
- pass |
- G5 |
- pass |
- F6 |
- pass |
- F7 |
- pass |
- E8 |
- pass |
- E9 |
- pass |
- F9 |
- pass |
- F4 |
- pass |
- F3 |
- pass |
- F2 |
- pass |
- E1 |
- pass |
- D2 |
- pass |
- D3 |
- E2 |
- E3 |
- pass |
- H4 |
- pass |
- H3 |
- pass |
- J3 |
- A9 |
- pass |
- A8 |
- pass |
- A7 |
- pass |
- B7 |
- pass |
- B6 |
- pass |
- C6 |
- pass |
- C5 |
- pass |
- C4 |
- pass |
- D4 |
- pass |
- E4 |
- pass |
- C3 |
- pass |
- C2 |
- pass |
- C1 |
- pass |
- D1 |
- pass |
- F8 |
- pass |
- G9 |
- pass |
- G8 |
- pass |
- G7 |
- pass |
- G6 |
- pass |
- H6 |
- pass |
- H5 |
- pass |
- J5 |
- pass |
- J4 |
- pass |
- J7 |
-
- #Black has surrounded 15 vacant points (10 in the lower right corner and 5
- #towards the top of the board), and white has 17 (11 in the lower left corner
- #and 6 in the upper right corner)
- # |
- #Players also score a point for each enemy stone they capture during the game.
- #In this game Black captured one prisoner stone, so his total score was 16.
- #White captured no stones but still won by one point.
- # |
- #It is not worth either player playing on any of the remaining vacant points
- #because any stones played would eventually be captured as there is no way
- #to make stones thus played into "invulnerable groups" (see later).
- # |
- #The game ends by mutual agreement, because both players can see that further
- #moves cannot benefit either of them.
- # |
- #Beginners who are in any doubt whether a game is finished are advised to
- #continue playing until the issue is quite clear to both players.
- # |
- #To demonstrate the way to capture stones in Go we shall now move on to a 13x13
- #board, note that the following situations are only to illustrate the rules of
- #Go and are unlikely to occur in a real game.
- 13 0|
-
- e8#The stone at e8 has four 'freedoms' at e9, f8, e7 and d8, when all it's
- #freedoms are occupied by opponents' stones then it will be captured.
- e9|
- pass|
- f8|
- pass|
- e7|
- pass|
- #e8 is now in 'atari' (which means "threat to capture" in Japanese), ie it has
- #only one freedom left, all that is required is for white to play at d8 and it
- #will be captured.
- d8|
- # |
- #Stones of the same colour can be connected into groups. The connections can
- #only be up, down or left, right but not diagonally.
- # |
- j7|
- pass|
- j6|
- #This two stone group has six freedoms at j8, k7, k6, j5, h6 and h7.
- #White surrounds all but one of its freedoms ...
- j8|
- pass|
- k7|
- pass|
- k6|
- pass|
- h7|
- pass|
- h6|
- #If black ignores this atari (threat to capture) by playing elsewhere
- #and white plays at j5 then the group will be removed.
- pass|
- j5
- # |
- #Groups against the sides and corners have correspondingly less freedoms ...
- A13|
- pass|
- b13|
- #This black group (A13, B13) has only 3 freedoms.
- # |
- #Another example ...
- pass|
- d1|
- c1|
- d2|
- c2|
- d3|
- c3|
- e3|
- d4|
- f4|
- e4|
- g4|
- e2|
- pass|
- e1|
- pass|
- f2|
- pass|
- g2|
- #Here are TWO black groups (the diagonal between E3-F3 means they are separated)
- #if it is white's move then playing at f3 will kill the four stone black
- #group, if it is black to play then f3 would connect the two groups ...
- f3|
- # ... giving it (the single black group) four freedoms (f5, g5, h4, g3).
- # |
- #It is illegal to play a stone in such a place that it will have no freedoms,
- #ie black cannot play at e8 as this is a "suicidal" move. If however the
- #situation was as follows ...
- pass|
- d9|
- pass|
- c8|
- pass|
- d7|
- pass|
- # ... then black may play at e8 because in playing there it removes the white
- #stone at d8, thus giving it (the black stone) one freedom.
- e8|
- # |
- #White cannot play immediately back in d8. This situation is called a 'ko'
- #Ko in Japanese means eternity and the rule of Ko forbids a "tit for tat"
- #infinite exchange. White must play elsewhere, hoping that black will answer
- #the move and then white can play back in d8, then black will have to find
- #a move that white will have to answer and so on. An example of a Ko battle is
- #explained more in "kobattle.go".
- 13 0|
- #Being unable to make suicidal move leads to the formation of "invulnerable
- #groups", for example ...
- m1|
- j1|
- k1|
- j2|
- k2|
- k3|
- l2|
- l3|
- m2|
- m3|
- n2|
- n3|
- # |
- #It is white's move but is unable to capture the black group in the corner
- #because it has 'two eyes' - white cannot play at L1 because the black
- #group has still one freedom at N1, thus this would be a suicidal (illegal)
- #move.
- # |
- #In the completed game shown earlier it would not be possible for a player
- #to invade the opponent's territory because there would be no room for the
- #"invader" to make two eyes so eventually the invaders' stones would be captured
- #When both players realise there is no point in playing in the remaining vacant
- #points on the board the game ends.
- # |
- #Go back to line 124 (with ^N), this will take you to the end of the completed
- #game shown earlier, use practice mode to satisfy yourself there is no room to
- #live in the remaining places (it is black to move next). To return to here,
- #goto line 262.
- # |
- #At the end of the game there may be remnants of groups abandoned (for example
- #in "example.go") it is not necessary to play these out, they are just treated
- #as captured when it comes to counting up at the end.
- SHAR_EOF
- fi
- if test -f 'bgj.75.go'
- then
- echo shar: "will not over-write existing file 'bgj.75.go'"
- else
- cat << \SHAR_EOF > 'bgj.75.go'
- 19 0 # Tudball (8) vs. Rudd (9)
- c4
- q3
- q16
- d17
- e4
- r14
- d15 #An excellent move, approaching White 4 (d17) while developing in front of
- #the shimari. Because of this, white should have prefered to play 6 (r14)
- #at d15, c15 or c14.
- c15
- c14
- c16
- d13
- c9 #If white had played at f17, to complete the joseki, then black would have
- #played on the left side getting good shape in relation to 1 and 5 (d4) (e4)
- #However this just gives black a target to aim at, other approaches to
- #consider are :-
- #(a) Complete the joseki and take sente to play elsewhere, worrying less
- #about blacks's postion and doing more about white's own.
- #(b) Use 8 (c15) to play a pincer immediately, without committing yourself to
- #one shape in the corner.
- #(c) Play 12 (c9) on the fourth line, for an easier escape into the centre.
- e9 #Black choses to confine white on the left side, still hoping to keep sente
- #and return to the vicinty of 4 (17) later.
- c12
- b14
- b15 #At this stage it is more important to get the corner group out into the
- #open at (f17) than to protect a few points of corner territory. But the
- #corner group cannot be killed yet, so a jump out to e11 would be better
- #still, moving out and separating black as well.
- d11
- b12
- d12
- f17
- #The left hand white group is very weak, it's ok to play elsewhere if it is
- #for something bigger, however there isn't anything bigger and both sides should
- #be eager to play here.
- O16
- R11
- R5
- R8
- #Trying to use R11 (22) to help attack.
- P5
- O3
- #Should be one position higher at O4 because of the strength of R8 and R11
- S3
- L3
- H3
- K5
- R2
- Q2
- N4
- M3
- N3
- N2
- O4
- P3
- Q7
- E14
- E15
- F15
- D14
- G14
- K16
- J17
- K17
- J18
- K18
- R17
- R16
- Q17
- P17
- S16
- S15
- T16
- R15
- S14
- T15
- S18
- Q18
- R18
- J16
- H17
- J14
- M15
- M16
- O14
- N15
- P15
- O15
- P14
- P16
- O9
- Q10
- R10
- P9
- Q11
- P11
- P12
- O11
- C6
- C10#This should have been a lot earlier, why wait to attack after white has
- #strenghtened the left side at d6 ?
- B10
- B11
- B9
- C11
- A11
- D7
- C7
- D6
- S6
- S5
- R7
- R6
- B5
- B4
- G5
- H5
- H4
- G4
- J4
- H6
- G3
- F4
- G2
- F2
- F3
- E2
- J3
- J9
- G12
- F13
- G13
- F14
- F12
- E13
- F16
- N9
- P8
- Q8
- M6
- N7
- E10
- E11
- E8
- D8
- D10
- D9
- F11
- F10
- J7
- H7
- J8
- H8
- K9
- O12
- O13
- L6
- L7
- L5
- M5
- K10
- L9
- L10
- H9
- J10
- G10
- G9
- H10
- F8
- N10
- O10
- M9
- N8
- N11
- M10
- N12
- O8
- J12
- K12
- J13
- K13
- K11
- J11
- L11
- H12
- H13
- G11
- H11
- M14
- P18
- O18
- Q19
- R9
- S9
- Q9
- S8
- C5
- B6
- C8
- B8
- H16
- G16
- Q14
- Q13
- Q15
- S13
- SHAR_EOF
- fi
- cd ..
- if test ! -d 'src'
- then
- mkdir 'src'
- fi
- cd 'src'
- if test -f 'c'
- then
- echo shar: "will not over-write existing file 'c'"
- else
- cat << \SHAR_EOF > 'c'
- case $TERM in
-
- 630) dmdcc -g -ogo.630.out go.c go.630.c -Ddmd ;\
- mv go.630.out $GO/bin ;;
-
- *) make ;;
-
- esac
- SHAR_EOF
- fi
- if test -f 'go.630.c'
- then
- echo shar: "will not over-write existing file 'go.630.c'"
- else
- cat << \SHAR_EOF > 'go.630.c'
- #include <dmd.h>
- #include <object.h>
-
- #include "go.h"
- #include "go.extern.h"
-
- #define byte unsigned short
-
- #include <font.h>
- short jwidths() ;
- short jputs() ;
- byte jputc() ;
- char initjput() ;
-
- #include "go_icon"
-
- #include "null_icon"
- #include "tick_icon"
- Bitmap bm_tick = { (Word *)tick_icon, 1, 0, 0, 15, 15, 0, } ;
- Bitmap bm_null = { (Word *)null_icon, 1, 0, 0, 15, 15, 0, } ;
-
-
- #define LEDGE 60 /* distance from top and left of board to window edge */
- #define GRIDSIZE 44 /* distance between the lines on the board */
- #define STONERADIUS 17
-
- #define GAP (GRIDSIZE-(STONERADIUS*2)) /* gap between neighbouring stones */
-
- /* the left hand edge of any text displayed */
- #define XSTARTPOS 20
-
- /* key definitions */
- #define BACKSPACE 8
- #define KILLLINE 127
- #define RETURN 13 /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
-
- /* Variables Global to this file */
- short lastwidth ; /* width of last lastmove string */
- int promptline ; /* position to write the next line of text */
- int linedisplayed ; /* number of lines displayed */
-
- BOOLEAN buttonpressedlasttime ;
-
- int HEDGE ; /* distance between right and bottom of board to the window edge*/
- char fontheight ; /* Height of the font */
-
-
- char dsize ; /* Used between downsize() and getinput() */
- MOVENUMBER hgoto; /* Used between hitgoto() and getinput() */
- char dgoto ; /* set by downgoto(), read by gotogenerator() and getinput() */
-
- /****************************************************************************/
- /* Menu variables */
- /****************************************************************************/
- #include <menu.h>
- void downsize() ;
- void downgoto() ;
- void hitgoto() ;
-
- #define size9 (spacebar+1) /* assumes spacebar is the last ACTIONTYPE */
- #define size13 (spacebar+2)
- #define size19 (spacebar+3)
-
- #define GOTOMOVE 0
- #define GOTOLINE 1
-
- Titem *gotogenerator() ;
- extern Tmenu menu00, menu10, menu11, menu12, menu20, menu21, menu22, menu30 ;
-
- typedef struct ROOTMENU
- {
- char *text ;
- struct {
- Word uval ;
- Word grey ;
- } ufield ;
- struct Tmenu *next ;
- Bitmap *icon ;
- } ROOTMENU ;
-
- typedef struct CONFIGMENU
- {
- char *text ;
- struct {
- Word uval ;
- Word grey ;
- } ufield ;
- struct Tmenu *next ;
- Bitmap *icon ;
- } CONFIGMENU ;
-
- typedef struct GOTOMENU
- {
- char *text ;
- struct {
- Word uval ;
- Word grey ;
- } ufield ;
- struct Tmenu *next ;
- void (*dfn)() ;
- } GOTOMENU ;
-
- typedef struct SIZEMENU
- {
- char *text ;
- struct {
- Word uval ;
- Word grey ;
- } ufield ;
- struct Tmenu *next ;
- void (*dfn)() ;
- } SIZEMENU ;
-
- typedef struct HANDICAPMENU
- {
- char *text ;
- struct {
- Word uval ;
- Word grey ;
- } ufield ;
- } HANDICAPMENU ;
-
- typedef struct VERSIONMENU
- {
- char *text ;
- } VERSIONMENU ;
-
- ROOTMENU rootmenu[] =
- {
- "practice",(Word)practice,0,0,0,
- "step through",(Word)stepthrough,0,0,0,
- "read from",(Word)readfrom,0,0,0,
- "undo",(Word)undo,0,0,0,
- "configure",0,0,&menu10,0,
- "pass", (Word)pass,0,0,0,
- "write to",(Word)writeto,0,0,0,
- "version",0,0,&menu11,0,
- "redraw",(Word)redraw,0,0,0,
- "cd",(Word)cd,0,0,0,
- "goto",0,0,&menu12,0,
- "quit", (Word)quit,0,0,0,
- 0
- };
-
- CONFIGMENU configmenu[] =
- {
- "numbers",(Word)numbers,0,0,0,
- "grid",(Word)grid,0,0,0,
- "last move",(Word)lastmove,0,0,0,
- "size",0,0,&menu20,0,
- 0
- };
-
- GOTOMENU gotomenu[] =
- {
- "move",GOTOMOVE,0,&menu21,downgoto,
- "line",GOTOLINE,0,&menu22,downgoto,
- 0
- } ;
-
- SIZEMENU sizemenu[] =
- {
- "9", (Word)size9,0,&menu30,downsize,
- "13",(Word)size13,0,&menu30,downsize,
- "19",(Word)size19,0,&menu30,downsize,
- 0
- };
-
- HANDICAPMENU handicapmenu[] =
- {
- "0", (Word)changehandicap,0,
- "2", (Word)changehandicap,0,
- "3", (Word)changehandicap,0,
- "4", (Word)changehandicap,0,
- "5", (Word)changehandicap,0,
- "6", (Word)changehandicap,0,
- "7", (Word)changehandicap,0,
- "8", (Word)changehandicap,0,
- "9", (Word)changehandicap,0,
- 0
- } ;
-
- VERSIONMENU versionmenu[] =
- {
- version,
- 0
- } ;
-
- Tmenu menu00 = { (Titem *)rootmenu,0, 0, 0, TM_TEXT|TM_NEXT|TM_UFIELD|TM_ICON } ;
- Tmenu menu10 = { (Titem *)configmenu,0, 0, 0, TM_TEXT|TM_NEXT|TM_ICON|TM_UFIELD } ;
- Tmenu menu11 = { (Titem *)versionmenu,0, 0, 0, TM_TEXT} ;
- Tmenu menu12 = { (Titem *)gotomenu,0,0,0,TM_TEXT|TM_UFIELD|TM_NEXT|TM_DFN } ;
- Tmenu menu21 = { (Titem *)0,0,0,gotogenerator,0 } ;
- Tmenu menu22 = { (Titem *)0,0,0,gotogenerator,0 } ;
- Tmenu menu20 = { (Titem *)sizemenu,0, 0, 0, TM_TEXT|TM_UFIELD|TM_DFN|TM_NEXT} ;
- Tmenu menu30 = { (Titem *)handicapmenu,0, 0, 0, TM_TEXT|TM_UFIELD };
- /*****************************************************************************/
-
- /*
- * Function: errorprint
- *
- * Description: Displays the string passed as an error message.
- *
- * Globals affected: none
- *
- */
- void
- errorprint(s)
- char *s ;
- {
- Lprintf("%s",s) ;
- Lprintf(" ... hit any key to continue") ;
- do
- wait(KBD) ;
- while ( kbdchar()==(-1) ) ;
- }
-
- /*
- * Function: displaylastmove
- *
- * Description: If the last move flag is set, display the string passed.
- *
- *
- * Globals affected: none
- *
- */
- void
- displaylastmove(str)
- char str[] ;
- {
- short w ;
-
-
- if (flag[LASTMOVE]==on)
- {
- jrectf( Rpt(Pt(HEDGE+GRIDSIZE*2-(lastwidth/2),
- LEDGE+GRIDSIZE*5-(fontheight/2)),
- Pt(HEDGE+GRIDSIZE*2+(lastwidth/2),
- LEDGE+GRIDSIZE*5+(fontheight/2)) ),
- F_CLR ) ;
-
- w = jwidths(str) ;
-
- (void)jputs( Pt(HEDGE+GRIDSIZE*2-(w/2),
- LEDGE+GRIDSIZE*5-(fontheight/2)),
- str,
- F_STORE) ;
-
- lastwidth = w ;
- }
- }
-
- /*
- * Function: erasescreen()
- *
- * Description: Clears the whole of the window.
- *
- * Globals affected: none
- *
- */
- erasescreen()
- {
- jrectf ( Rpt(Pt(0,0),Pt(XMAX-1,YMAX-1)), F_CLR ) ;
- }
-
- /*
- * Function: reconfigure
- *
- * Description: The size of the board has changed, set variables accordingly.
- *
- *
- * Globals affected: HEDGE, promptline
- *
- */
- reconfigure()
- {
- char i ;
-
- HEDGE = ( size - 1 ) * GRIDSIZE + LEDGE ;
-
- promptline = HEDGE + STONERADIUS + fontheight ;
-
- }
-
- /*
- * Function: getinput()
- *
- * Description: Gets input from keyboard or mouse.
- * Sets action to be one of the following, with corresponding
- * data in the buffer.
- * Any strings returned in the buffer always end with a newline
- * and a null.
- *
- * action actbuffer
- * ------ ---------
- * cd null
- * gotomove Decimal byte string "1" to "999", ending with
- * newline. Maximum of four bytes long, plus '\0'.
- * gotoline decimal string "1" to "999" ending with newline.
- * Maximum of four bytes long, plus '\0'.
- * changehandicap first byte is size, second is handicap
- * numbers null
- * pass null
- * practice null
- * quit null
- * rawkeyboard string typed in from the keyboard
- * readfrom null
- * redraw null
- * changesize first byte indicates new size
- * spacebar null
- * stoneplayed x and y in the first two bytes
- * stepthrough null
- * undo null
- * writeto null
- *
- * This function handles the displaying of the menu (together
- * with the associated flags). The current move must be
- * displayed on the menu in a relevant place.
- *
- * Globals affected: buttonpressedlasttime
- *
- */
- getinput ( action, actbuffer )
- ACTIONTYPE *action ;
- char actbuffer[MAXLINELENGTH] ;
- {
- Titem *ret ;
- Point mouseat ;
- int keypressed ;
- byte width ;
-
- wait(MOUSE|KBD);
- if (*action!=noselection)
- cursswitch( &go_icon ) ;
-
- if (buttonpressedlasttime == TRUE)
- {
- /* need to sleep to avoid button bounce */
- sleep(15) ;
- }
-
- /* reset value */
- buttonpressedlasttime = FALSE ;
-
- *action = noselection ;
- if (button1())
- {
- *action = stoneplayed ;
- mouseat = mouse.jxy ;
- actbuffer[0]=(mouseat.x-LEDGE+(GRIDSIZE/2))/GRIDSIZE + 1;
- actbuffer[1]=(mouseat.y-LEDGE+(GRIDSIZE/2))/GRIDSIZE + 1;
- buttonpressedlasttime = TRUE ;
- }
-
- if (button2())
- {
- *action = spacebar ;
- buttonpressedlasttime = TRUE ;
- }
-
- hgoto = 0 ; /* initialise */
-
- if (button3())
- {
- ret=tmenuhit (&menu00,3,TM_EXPAND) ;
-
-
- if (ret!=0)
- {
- if (hgoto==0)
- {
- switch (ret->ufield.uval)
- {
- case size9 :
- actbuffer[0] = 9 ;
- *action = changesize ;
- break ;
- case size13 :
- actbuffer[0] = 13 ;
- *action = changesize ;
- break ;
- case size19 :
- actbuffer[0] = 19 ;
- *action = changesize ;
- break ;
-
- case changehandicap :
- actbuffer[0] = dsize ;
- if (menu30.prevhit!=0)
- {
- actbuffer[1] = menu30.prevhit+1 ;
- }
- else
- {
- actbuffer[1] = 0 ;
- }
- *action = changehandicap ;
- break ;
-
- default :
- *action = (ACTIONTYPE)ret->ufield.uval ;
- break ;
- }
- }
- else
- {
- actbuffer[0] = 0 ;
- sprintf(actbuffer,"%d\n",hgoto ) ;
-
- if (dgoto==GOTOMOVE)
- *action = gotomove ;
- else
- *action = gotoline ;
- }
- }
-
- buttonpressedlasttime = TRUE ;
-
- } /* end button 3 */
-
-
- if ( (keypressed=kbdchar()) != (-1) )
- {
- if ((char)keypressed==' ')
- *action = spacebar ;
- else
- {
- *action = rawkeyboard ;
- actbuffer[0] = (char)keypressed ;
- width = jputc( Pt(XSTARTPOS,promptline),
- (char)keypressed,
- F_STORE) ;
- collectstring(Pt(XSTARTPOS,promptline),
- Pt(XSTARTPOS+width,promptline),
- actbuffer,1 , MAXCHARS ) ;
- strcat(actbuffer,"\n") ;
- }
-
- } /* end if key pressed */
-
- }
-
-
- /*
- * Function: drawgrid
- *
- * Description: Check if the grid flag is on , if so display the 'A' to 'T'
- * across the top and 19 to 1 down the left.
- *
- *
- * Globals affected: none
- *
- */
- drawgrid()
- {
- int i,j ;
- char numberstring[3] ;
-
- if (flag[GRID]==on)
- {
- for (i=1;i<=size;i++)
- for (j=1;j<=size;j++)
- {
- if (i==1)
- {
- ctostr(size-j+1,numberstring) ;
- (void)jputs( 0,
- ((j-1)*GRIDSIZE)+LEDGE-(fontheight/2),
- numberstring ) ;
-
- }
- if (j==1)
- {
- if (i<=8)
- (void)jputc((i-1)*GRIDSIZE+LEDGE,10+(fontheight/2),i+'A'-1) ;
- else
- (void)jputc((i-1)*GRIDSIZE+LEDGE,10+(fontheight/2),i+'J'-9) ;
- }
- }
-
- }
- }
-
- /*
- * Function: drawempty
- *
- * Description: Draws an empty position of the board, if this x,y is a handicap
- * point then draw a black dot as well.
- *
- *
- * Globals affected: none
- *
- */
- drawempty(x,y)
- COORD x,y ;
- {
- Point actual ;
-
-
- if ( (x==1) && (y==1) )
- {
- jbox(Rect(LEDGE-STONERADIUS-2,
- LEDGE-STONERADIUS-2,
- HEDGE+STONERADIUS+2,
- HEDGE+STONERADIUS+2) ) ;
- }
-
- actual.x = (x-1)*GRIDSIZE+LEDGE;
- actual.y = (y-1)*GRIDSIZE+LEDGE ;
-
- jdisc(actual,STONERADIUS,F_CLR) ;
-
- switch ( (int)postype(x,y) )
- {
- case topleft :
- jsegment(Pt(LEDGE,LEDGE),
- Pt(LEDGE+STONERADIUS+GAP,LEDGE),
- F_STORE ) ;
- jsegment(Pt(LEDGE,LEDGE),
- Pt(LEDGE,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
- case topside :
- jsegment(Pt(actual.x-STONERADIUS,LEDGE),
- Pt(actual.x+STONERADIUS+GAP,LEDGE),
- F_STORE ) ;
- jsegment(Pt(actual.x,LEDGE),
- Pt(actual.x,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
- case topright :
- jsegment(Pt(HEDGE-STONERADIUS,LEDGE),
- Pt(HEDGE,LEDGE),
- F_STORE ) ;
- jsegment(Pt(HEDGE,LEDGE),
- Pt(HEDGE,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
- case leftside :
- jsegment(Pt(LEDGE,actual.y),
- Pt(LEDGE+STONERADIUS+GAP,actual.y),
- F_STORE ) ;
- jsegment(Pt(LEDGE,actual.y-STONERADIUS),
- Pt(LEDGE,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
- case middle :
- jsegment(Pt(actual.x-STONERADIUS,actual.y),
- Pt(actual.x+STONERADIUS+GAP,actual.y),
- F_STORE ) ;
- jsegment(Pt(actual.x,actual.y-STONERADIUS),
- Pt(actual.x,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- if (starpoint(x,y))
- {
- putstar(actual) ;
- }
- break ;
- case rightside :
- jsegment(Pt(HEDGE-STONERADIUS,actual.y),
- Pt(HEDGE,actual.y),
- F_STORE ) ;
- jsegment(Pt(actual.x,actual.y-STONERADIUS),
- Pt(actual.x,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
- case bottomleft :
- jsegment(Pt(LEDGE,HEDGE),
- Pt(LEDGE+STONERADIUS+GAP,HEDGE),
- F_STORE ) ;
- jsegment(Pt(LEDGE,HEDGE-STONERADIUS),
- Pt(LEDGE,HEDGE),
- F_STORE ) ;
- break ;
- case bottomside :
- jsegment(Pt(actual.x-STONERADIUS,HEDGE),
- Pt(actual.x+STONERADIUS+GAP,HEDGE),
- F_STORE ) ;
- jsegment(Pt(actual.x,HEDGE-STONERADIUS),
- Pt(actual.x,HEDGE),
- F_STORE ) ;
- break ;
- case bottomright :
- jsegment(Pt(HEDGE-STONERADIUS,HEDGE),
- Pt(HEDGE,HEDGE),
- F_STORE ) ;
- jsegment(Pt(HEDGE,HEDGE-STONERADIUS),
- Pt(HEDGE,HEDGE),
- F_STORE ) ;
- break ;
- default :
- errorprint ( "error in draw empty" ) ;
- break ;
- }
- }
-
- /*
- * Function: drawstone
- *
- * Description: Draw a stone of colour c at coordinates (x,y), the move number
- * is n. Do not display the number if this is a handicap stone or
- * practice flag is on or if numbers flag is off.
- *
- * Globals affected: none
- *
- */
- drawstone(x,y,n,colour)
- COORD x,y ;
- MOVENUMBER n ;
- COLOUR colour ;
- {
-
- Point actual ;
-
-
- if ( (x==1) && (y==1) )
- {
- jbox(Rect(LEDGE-STONERADIUS-2,
- LEDGE-STONERADIUS-2,
- HEDGE+STONERADIUS+2,
- HEDGE+STONERADIUS+2) ) ;
- }
-
- actual.x = (x-1)*GRIDSIZE+LEDGE;
- actual.y = (y-1)*GRIDSIZE+LEDGE ;
-
-
- if (starpoint(x,y) && (n==2) && (handicap!=0) )
- {
- jdisc (actual, STONERADIUS, F_OR ) ;
- }
- else
- if (colour==black)
- {
- jdisc (actual, STONERADIUS, F_OR ) ;
- if ( (flag[PRACTICE]==off) &&
- (flag[NUMBERS]==on) )
- putnumber(actual,black,n) ;
- }
- else
- if (colour==white)
- {
- jdisc (actual, STONERADIUS, F_CLR ) ;
- jcircle ( actual, STONERADIUS, F_OR ) ;
- if ( (flag[PRACTICE]==off) &&
- (flag[NUMBERS]==on) )
- putnumber(actual,white,n) ;
- }
- else
- {
- errorprint("error in drawstone") ;
- }
-
- switch ( (int)postype(x,y) )
- {
- case topleft :
- jsegment ( Pt(LEDGE+STONERADIUS,LEDGE),
- Pt(LEDGE+STONERADIUS+GAP,LEDGE),
- F_STORE ) ;
- jsegment ( Pt(LEDGE,LEDGE+STONERADIUS),
- Pt(LEDGE,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case topside :
- jsegment ( Pt(actual.x+STONERADIUS,LEDGE),
- Pt(actual.x+STONERADIUS+GAP,LEDGE),
- F_STORE ) ;
- jsegment ( Pt(actual.x,LEDGE+STONERADIUS),
- Pt(actual.x,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case topright :
- jsegment ( Pt(HEDGE,LEDGE+STONERADIUS),
- Pt(HEDGE,LEDGE+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case leftside:
- jsegment ( Pt(LEDGE+STONERADIUS,actual.y),
- Pt(LEDGE+STONERADIUS+GAP,actual.y),
- F_STORE ) ;
- jsegment ( Pt(LEDGE,actual.y+STONERADIUS),
- Pt(LEDGE,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case middle :
- jsegment ( Pt(actual.x+STONERADIUS,actual.y),
- Pt(actual.x+STONERADIUS+GAP,actual.y),
- F_STORE ) ;
- jsegment ( Pt(actual.x,actual.y+STONERADIUS),
- Pt(actual.x,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case rightside :
- jsegment ( Pt(HEDGE,actual.y+STONERADIUS),
- Pt(HEDGE,actual.y+STONERADIUS+GAP),
- F_STORE ) ;
- break ;
-
- case bottomleft :
- jsegment ( Pt(LEDGE+STONERADIUS,HEDGE),
- Pt(LEDGE+STONERADIUS+GAP,HEDGE),
- F_STORE ) ;
- break ;
-
- case bottomside :
- jsegment ( Pt(actual.x+STONERADIUS,HEDGE),
- Pt(actual.x+STONERADIUS+GAP,HEDGE),
- F_STORE ) ;
- break ;
-
- case bottomright :
- break ;
-
- default :
- errorprint("error in case in drawstone") ;
- break ;
-
- } /* end switch postype */
-
- }
-
- /*
- * Function: getdirectory
- *
- * Description: If directory is already set then copy directory into dn.
- * Display dn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected: none
- *
- */
- getdirectory(dn)
- char dn[] ;
- {
- short w1,w2 ;
-
- clearpromptline() ;
-
- if (directory[0]!=0)
- {
- strcpy(dn,directory) ;
- }
- else
- {
- dn[0] = 0 ;
- }
-
- w1 = jputs(Pt(XSTARTPOS,promptline),"Enter directory : ",F_STORE) ;
-
- w2 = jputs(Pt(XSTARTPOS+w1,promptline),dn,F_STORE) ;
-
- collectstring(Pt(XSTARTPOS+w1,promptline),
- Pt(XSTARTPOS+w1+w2,promptline),
- dn,strlen(dn),
- MAXCHARS ) ;
-
- clearpromptline() ;
- }
-
- /*
- * Function: getfilename
- *
- * Description: If filename is already set then copy filename into fn.
- * Display fn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected: none
- *
- */
- getfilename(fn)
- char fn[] ;
- {
- short w1,w2 ;
-
- clearpromptline() ;
-
- if (filename[0]!=0)
- {
- strcpy(fn,filename) ;
- }
- else
- {
- fn[0] = 0 ;
- }
-
- w1 = jputs(Pt(XSTARTPOS,promptline),"Enter filename : ",F_STORE) ;
-
- w2 = jputs(Pt(XSTARTPOS+w1,promptline),fn,F_STORE) ;
-
- collectstring(Pt(XSTARTPOS+w1,promptline),
- Pt(XSTARTPOS+w1+w2,promptline),
- fn,strlen(fn),
- FILENAMELEN ) ;
-
- clearpromptline() ;
- }
-
- /*
- * Function: displaycaptured
- *
- * Description: Display teh number of stones taken off.
- *
- * Globals affected: none
- *
- */
- void
- displaycaptured()
- {
- Point actual ;
-
- actual.x = HEDGE + ( GRIDSIZE * 2 ) ;
- actual.y = LEDGE + ( GRIDSIZE * 2 ) ;
-
-
- jdisc (actual, STONERADIUS, F_OR ) ;
- putnumber(actual,black,blackcaptured) ;
-
- actual.y = LEDGE + ( GRIDSIZE * 3 ) ;
-
- jdisc (actual, STONERADIUS, F_CLR ) ;
- jcircle ( actual, STONERADIUS, F_OR ) ;
- putnumber(actual,white,whitecaptured) ;
-
- }
-
- /*
- * Function: refreshmenu()
- *
- * Description: This function is called when some information on the menu
- * has changed, the screen needs updating.
- *
- *
- * Globals affected: none
- *
- */
- void
- refreshmenu()
- {
- displayflag(STEPPING) ;
- displayflag(PRACTICE) ;
- displayflag(NUMBERS) ;
- displayflag(GRID) ;
- displayflag(LASTMOVE) ;
- }
-
- /*
- * Function: clearpromptline
- *
- * Description: Rather than scroll up the prompt display area, this routine
- * increments promptline downwards until there is no room to
- * write another line of text, in which case it clears the whole
- * display area.
- *
- * Globals affected: promptline
- *
- */
- clearpromptline()
- {
- if ( promptline + (fontheight*2) > YMAX )
- {
- jrectf ( Rpt(Pt(XSTARTPOS,HEDGE+STONERADIUS+fontheight),
- Pt(XMAX-1,promptline+fontheight) ),
- F_CLR ) ;
- promptline = HEDGE + STONERADIUS + fontheight ;
- }
- else
- promptline += fontheight ;
- }
-
- /*
- * Function: displaystring()
- *
- * Description: Display s on the promptline.
- *
- * Globals affected: none
- *
- */
- displaystring(s)
- char *s ;
- {
- (void)jputs(Pt(XSTARTPOS,promptline),s ,F_STORE) ;
- }
-
- /*
- * Function: startterminalspecific
- *
- * Description: Initailise variables for start of program, cache the
- * application if required in the parameters, reshape the
- * window to be square taking the width already drawn to
- * be the size.
- *
- * Globals affected: fontheight, buttonpressedlasttime, promptline
- *
- */
- void
- startterminalspecific(argc,argv)
- int argc ;
- char *argv[] ;
- {
-
- int i ;
- int width ;
- int newheight ;
- int oldheight ;
- int heightdiff ;
-
- width = Drect.corner.x - Drect.origin.x ;
- oldheight = Drect.corner.y - Drect.origin.y ;
- newheight = width ;
- heightdiff = newheight - oldheight ;
-
- reshape( Rpt( Pt( Drect.origin.x, Drect.origin.y - heightdiff/2 ),
- Pt( Drect.corner.x, Drect.corner.y + heightdiff/2 ) ) ) ;
-
-
- fontheight = initjput() ;
-
- request(MOUSE|KBD);
-
- cursswitch( &go_icon ) ;
-
- buttonpressedlasttime = FALSE ;
-
- promptline = fontheight ; /* start at the top of the screen*/
-
- /* "-c" in the parameters represents a request to cache */
- for (i=1 ; i<argc ; i++)
- {
- if (strcmp("-c",argv[i]) == 0 )
- {
- cache((char *)0,A_NO_SHOW) ;
- }
- }
- }
-
- /*
- * Function: endterminalspecific
- *
- * Description: The program is closing down, de-initialise any data, release
- * resources etc.
- * (no action required for the 630)
- *
- * Globals affected: none
- *
- */
- void
- endterminalspecific()
- {
- }
-
- /******************************/
- /* End of Interface Functions */
- /******************************/
-
-
- /*
- * Function: displayflag()
- *
- * Description: Display the required flag on the menu.
- *
- * Globals affected: none
- *
- */
- displayflag(f)
- char f ;
- {
- Bitmap *symbol ;
-
- if (flag[f]==off)
- symbol = &bm_null ;
- else
- symbol = &bm_tick ;
-
-
- switch(f)
- {
- case STEPPING : rootmenu[1].icon = symbol ;
- break ;
- case PRACTICE : rootmenu[0].icon = symbol ;
- break ;
- case NUMBERS : configmenu[0].icon = symbol ;
- break ;
- case GRID : configmenu[1].icon = symbol ;
- break ;
- case LASTMOVE : configmenu[2].icon = symbol ;
- break ;
- default : errorprint("Default case in displayflag()") ;
- break ;
- }
- }
-
- /*
- * Function: downgoto
- *
- * Description: This function is entered when sliding down into goto a
- * move or line.
- *
- *
- * Globals affected: dgoto
- *
- */
- void
- downgoto(mi)
- Titem *mi ;
- {
- dgoto = mi->ufield.uval ;
- }
-
- /*
- * Function: downsize()
- *
- * Description: This is entered when the mouse slides down into the
- * handicap menu.
- *
- *
- * Globals affected: dsize
- *
- */
- void
- downsize(mi)
- Titem *mi ;
- {
- switch (mi->ufield.uval)
- {
- case size9 : handicapmenu[5].ufield.grey = 1 ;
- handicapmenu[6].ufield.grey = 1 ;
- handicapmenu[7].ufield.grey = 1 ;
- handicapmenu[8].ufield.grey = 1 ;
- dsize = 9 ;
- break ;
- case size13 : handicapmenu[5].ufield.grey = 1 ;
- handicapmenu[6].ufield.grey = 1 ;
- handicapmenu[7].ufield.grey = 1 ;
- handicapmenu[8].ufield.grey = 1 ;
- dsize = 13 ;
- break ;
- case size19 : handicapmenu[5].ufield.grey = 0 ;
- handicapmenu[6].ufield.grey = 0 ;
- handicapmenu[7].ufield.grey = 0 ;
- handicapmenu[8].ufield.grey = 0 ;
- dsize = 19 ;
- break ;
- default : errorprint("error in downsize");
- break ;
- }
-
-
-
- }
-
- /*
- * Function: hitgoto
- *
- * Description: This is entered when the mouse is clicked on the goto menu.
- *
- *
- * Globals affected: hgoto
- *
- */
- void
- hitgoto(mi)
- Titem *mi ;
- {
- hgoto = mi->ufield.uval ;
- }
-
-
- /*
- * Function: gotogenerator()
- *
- * Description: This is entered when the goto menu is first selected, it
- * dynamically generates the list of numbers to goto.
- *
- *
- * Globals affected: gotomenuitem, s[]
- *
- */
- Titem gotomenuitem ;
- char s[4] ;
-
- Titem *
- gotogenerator(i,m)
-
- int i ;
- Tmenu *m ;
- {
-
- if (i>998)
- {
- gotomenuitem.text = 0 ;
-
- if (dgoto==GOTOMOVE)
- {
- if (currentmove < 9)
- menu21.prevtop = 0 ;
- else
- menu21.prevtop = currentmove - 10 ;
- }
- else
- {
- if (steppingindex < 8)
- menu22.prevtop = 0 ;
- else
- menu22.prevtop = steppingindex - 9 ;
- }
- }
- else
- {
- s[0] = 0 ;
- sprintf(s,"%d",i+1) ;
- gotomenuitem.text = s ;
- gotomenuitem.ufield.uval = i + 1 ;
- if (dgoto==GOTOMOVE)
- {
- if ((currentmove-2) == i )
- gotomenuitem.ufield.grey = 1 ;
- else
- gotomenuitem.ufield.grey = 0 ;
- }
- else
- {
- if ( (steppingindex-1) == i)
- gotomenuitem.ufield.grey = 1 ;
- else
- gotomenuitem.ufield.grey = 0 ;
- }
- gotomenuitem.hfn = hitgoto ;
-
- }
-
- return(&gotomenuitem) ;
- }
-
-
- /*
- * Function: ctostr()
- *
- * Description: Puts a right justified string of c into area pointed to
- * by p. The length of p will always be three.
- *
- *
- * Globals affected: none
- *
- */
- ctostr(c,p)
- unsigned char c ;
- char *p ;
- {
- #define LEN 3
- int dec,index ;
-
- for (index=0 ; index<LEN ;index ++)
- {
- *(p+index) = ' ' ;
- }
-
- *(p+LEN) = '\0' ;
-
- dec = LEN ;
-
- do
- {
- dec-- ;
- *(p+dec) = (c%10) + '0' ;
- c = c/10 ;
- }
- while (c!=0) ;
-
- }
-
-
-
- /*
- * Function: collectstring()
- *
- * Description: Allows player to input and edit a string displayed on promptline
- * Editting keys are backspace and delete (to kill a line)
- * The resultant string is in p.
- *
- * Globals affected: none
- *
- */
- collectstring ( sat, at, p, l, max )
- Point sat ; /* point to start of string already displayed */
- Point at ; /*point at which to start displaying */
- char *p ; /* pointer to the buffer */
- char l ; /* length of buffer aleady filled */
- char max ; /* limit of number of characters */
- {
- char c,w ;
-
- cursswitch(&C_insert) ; /* new cursor to prompt the player for text */
-
- w = 0 ;
- c = 0 ;
- while (c!=RETURN)
- {
- wait(KBD) ;
- c = (char)kbdchar() ;
- if (c!=(-1))
- {
- switch (c)
- {
- case RETURN:
- break ;
- case BACKSPACE:
- if (l>0)
- {
- l-- ;
- w = jwidths(p+l) ;
- at.x -= w ;
- jrectf(Rpt(at,Pt(at.x+w,at.y+fontheight)),F_CLR) ;
- jmove(at) ;
- *(p+l) = '\0' ;
- }
- break ;
- case KILLLINE:
- at = sat ;
- jrectf(Rpt(sat,Pt(1023,sat.y+fontheight)),F_CLR) ;
- jmove(sat) ;
- l = 0;
- break ;
- default:
- if ( l < max )
- {
- *(p+l) = (char)c ;
- l++ ;
- *(p+l) ='\0' ;
- w = jputc(Pt(at.x,at.y),(char)c,F_STORE) ;
- at.x += w ;
- }
- break ;
- }
- }
- }
- }
-
- /*
- * Function: jbox
- *
- * Description: Draws a box scaled to the window
- *
- *
- *
- * Globals affected: none
- *
- */
- jbox(r)
- Rectangle r;
- {
- jsegment (r.origin, Pt(r.corner.x,
- r.origin.y), F_STORE);
- jsegment (Pt(r.corner.x, r.origin.y),
- r.corner, F_STORE);
- jsegment (r.corner, Pt(r.origin.x,
- r.corner.y), F_STORE);
- jsegment (Pt(r.origin.x, r.corner.y),
- r.origin, F_STORE);
- }
-
- /*
- * Function: putnumber
- *
- * Description: Puts a number n onto the stone at point p whose colur is c.
- *
- * Globals affected: none
- *
- */
- putnumber(p,c,n)
- Point p ;
- COLOUR c ;
- MOVENUMBER n ;
- {
- short width ;
- char str[4] ;
- Code f ;
-
- if (c==black)
- f=F_CLR ;
- else
- f=F_STORE ;
-
- ctostr((unsigned char)n,str) ;
-
- if (n<10)
- {
- width =jwidths(&str[2]) ;
- jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), &str[2], f ) ;
- } else
- if (n<100)
- {
- width =jwidths(&str[1]) ;
- jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), &str[1], f ) ;
- } else
- if (n<1000)
- {
- width =jwidths(str) ;
- jputs(Pt(p.x-(width/2),p.y-(fontheight/2)), str, f ) ;
- }
-
- }
-
- /*
- * Function: putstar()
- *
- * Description: Draws a star point (a black dot) at p.
- *
- *
- *
- * Globals affected: none
- *
- */
- putstar(p)
- Point p ;
- {
- jdisc(p,STONERADIUS/3,F_STORE) ;
- }
-
- /*
- * Jput routines
- *
- * These functions look directly at the memory location for the built-in
- * 'Large' font and use jpoint to display each individual bit/pixel so
- * that the text is scaled to the window.
- */
-
-
-
- char *pbitmap ; /* pointer to the start of the bitmap */
- Font *font;
- Fontchar *i;
-
-
- char
- initjput() /* need to initialise the global data */
- {
- font = &largefont;
- pbitmap = (char *)font->bits->base;
- return(font->height) ;
- }
-
- short
- jwidths(s) /* return the width of s in pixels */
- char *s ;
- {
- short swidth ;
- byte cwidth ;
-
-
- swidth = 0 ;
- while (*s!='\0')
- {
- i = (Fontchar *)((char *)font + 12 + ( 6 * (*s) ) );
- swidth += (i->width) ;
- s++ ;
- }
-
- return (swidth) ;
-
- }
- short
- jputs(p,s,f) /* put a string s starting at p using f format */
- Point p ;
- char *s ;
- Code f ;
- {
- short swidth ;
- byte cwidth ;
-
-
- swidth = 0 ;
- while ( (*s!='\0') && (*s!='\n') )
- {
- cwidth = jputc(Pt(p.x+swidth,p.y),*s,f) ;
- swidth += cwidth ;
- s++ ;
- }
-
- return (swidth) ;
-
- }
-
- byte
- jputc( p, c, f ) /* put a char c at p using format f */
- Point p;
- char c;
- Code f ;
- {
-
- register xindex,yindex ;
- byte Nthbit() ;
-
- if (c=='\t') c=' ' ; /* screen tabs */
-
- i = (Fontchar *)((char *)font + 12 + ( 6*c) );
-
-
- for (xindex=(i->left) ; xindex < (i->width) ; xindex++ )
- {
- for (yindex=(i->top) ; yindex <= (i->bottom) ; yindex++ )
- {
- if (Nthbit( (i->x)+xindex +
- ( yindex * (font->bits->width) * 16 ) ) )
- {
- jpoint (Pt(p.x+xindex,p.y+yindex),f) ;
- }
- }
- }
-
- return (i->width) ;
- }
-
-
- byte
- Nthbit (N) /* Returns the value of the Nth bit after pbitmap */
- int N ;
- {
- char actualbyte ;
- byte shiftindex ;
-
- actualbyte = *(pbitmap + (N/8) ) ;
-
- shiftindex = 7 - (N%8) ;
-
- return( (actualbyte>>shiftindex) & 0x01) ;
- }
- SHAR_EOF
- fi
- if test -f 'go.c'
- then
- echo shar: "will not over-write existing file 'go.c'"
- else
- cat << \SHAR_EOF > 'go.c'
- #include <string.h>
- #include <sys/types.h>
-
- #include "go.h"
- #include "go.interface.h"
- #include "go.patch.h"
-
-
- #include <malloc.h>
-
-
- /****************************************************************************/
- /* Global variables */
- /****************************************************************************/
-
- char version[] = "v1.0" ;
- char size ; /* size of the board */
- char handicap ; /* number of handicap stones */
-
- COLOUR black ;
- COLOUR white ;
-
- MOVENUMBER currentmove ; /* currentmove is the number of the next stone
- * to be played for 'real' ie not practice
- */
-
- int steppingindex ; /* used while stepping through raw[] */
- /* Points to the next one to translate */
-
- char filename[FILENAMELEN] ;
- char directory[MAXLINELENGTH] ;
-
- ONOFF flag[5] ;
-
- int blackcaptured ;
- int whitecaptured ;
-
- /*
- * Explanation of terms :-
- * "Raw" is used to describe text input by the player to represent
- * a move eg 'K5' or 'pass' this has to be "translated" into the x
- * and y coordinates of the board. "conversion" is when the (x,y)
- * coordinates have to presented as "raw".
- */
-
- /********************************************/
- /* Types and defines just used in this file */
- /********************************************/
-
- typedef enum RAWTYPE
- {
- nullraw,
- amove,
- newgame,
- control,
- rawerror,
- } RAWTYPE ;
-
- #define MAXRAW 400
-
- #define ILLEGALAT "Illegal move or unrecognised input at line "
- #define ILLEGAL "Illegal move or unrecognised input"
-
- /***************************************/
- /* Static variables just for this file */
- /***************************************/
-
- FILE *fptr ;
-
- /* These "saved" variables are to restore after an undo command */
- int savedblackcaptured ;
- int savedwhitecaptured ;
- MOVENUMBER savedcurrentmove ;
- COLOUR savednextpracticestone ;
- XY savedkomove ;
- char savedlastmovestring[5] ;
-
-
- char tempfilename[FILENAMELEN] ;
- char tempdirectory[MAXLINELENGTH] ;
-
- /* Used in directoryplus() */
- char fullfilename[MAXLINELENGTH + FILENAMELEN] ;
-
- char *raw[MAXRAW] ; /* Array of pointers to the
- * text of a file read in or
- * moves entered by players
- */
-
- int rawindex ; /* The number of elements in raw[] */
-
- int writeindex ; /* Number of elements in raw[] written away*/
-
- int undorawindex ; /* Marker of when the board was last saved */
-
- int lastreconfigure ; /* Marker of when the current game started */
-
- MOVENUMBER realboard[MAX][MAX] ; /* Moves are stored in these arrays */
- MOVENUMBER practiceboard[MAX][MAX] ; /* by movenumber, eg if an element is */
- MOVENUMBER undoboard[MAX][MAX] ; /* zero that position is empty */
- MOVENUMBER undopracticeboard[MAX][MAX] ;
-
- COLOUR nextpracticestone ; /* During practice this is the 'colour'
- * of the next practice stone.
- */
-
- /* Positions of the star points (the middle */
- /* point of a 19x19 is treated differently) */
- XY handicap9[5] = { {3,7} , {7,3} , {7,7} , {3,3} , {5,5} } ;
- XY handicap13[5] = { {4,10} , {10,4} , {10,10} , {4,4} , {7,7} } ;
- XY handicap19[8] = { {4,16} , {16,4} , {16,16} , {4,4} ,
- {4,10} , {16,10} , {10,4} , {10,16} } ;
-
- /* Used in checkcapture() checksurrounded() docheck() */
- int captured ;
- int checking ;
- XY deadstones[100] ; /* this list starts at 1 */
-
-
- XY komove ; /* stores the ko position, otherwise both fields are zero */
-
- char lastmovestring[5] ; /* A raw string of the last move */
-
-
-
-
- /*
- * Function: copyboard
- *
- * Description: Copies an array from one to the other.
- *
- *
- *
- * Globals affected: none
- *
- */
- copyboard(from,to)
- MOVENUMBER from[MAX][MAX] ;
- MOVENUMBER to[MAX][MAX] ;
- {
- int i,j ;
-
- for (i=1;i<=size;i++)
- for (j=1;j<=size;j++)
- to[i][j] = from[i][j] ;
- }
-
- /*
- * Function: stonecolour
- *
- * Description: Works on the number of the stone to determine it's
- * colour. If the number is odd and there is no handicap,
- * or if the number is even and there is a handicap then
- * the colour is black, else it is white.
- *
- *
- *
- * Globals affected: none
- *
- */
- COLOUR
- stonecolour(n)
- MOVENUMBER n ;
- {
- COLOUR retval ;
-
- if (n==0)
- retval = EMPTY ;
- else
- {
- if ( ((handicap!=0) && ((n%2)==0)) ||
- ((handicap==0) && ((n%2)!=0)) )
- retval = black ;
- else
- retval = white ;
- }
-
- return(retval) ;
- }
-
- /*
- * Function: directoryplus
- *
- * Description: Returns a pointer to string that contains the directory
- * plus the filename passed as parameter
- *
- *
- *
- * Globals affected: fullfilename[]
- *
- */
- char *
- directoryplus(fn)
- char *fn ;
- {
- fullfilename[0] =0 ;
- strcat(fullfilename,directory) ;
- strcat(fullfilename,"/") ;
- strcat(fullfilename,fn) ;
-
- return(fullfilename) ;
- }
-
- /*
- * Function: drawboard()
- *
- * Description: Draws the realboard[][] according to size and flag[GRID] and
- * also shows the number of stones captured.
- *
- *
- * Globals affected: none
- *
- */
- drawboard()
- {
-
- COORD i,j ;
- MOVENUMBER stonenumber ;
-
- for (i=1;i<=size;i++)
- for (j=1;j<=size;j++)
- {
- if (flag[PRACTICE]==off)
- stonenumber = realboard[i][j] ;
- else
- stonenumber = practiceboard[i][j] ;
-
- placestone(i,j,stonenumber) ;
- }
- drawgrid() ;
-
- displaycaptured() ;
-
- displaylastmove(lastmovestring) ;
- }
-
- /*
- * Function: putstarpoints()
- *
- * Description: Initialises realboard[][] with the handicap stones
- * (which always have a 'move number' of two)
- *
- *
- * Globals affected: realboard[][]
- *
- */
- putstarpoints()
- {
- int i ;
- int temphandicap ;
-
- if (size==9)
- {
- for (i=0;i<handicap;i++)
- {
- realboard[handicap9[i].x][handicap9[i].y] = black ;
- }
- }
- if (size==13)
- {
- for (i=0;i<handicap;i++)
- {
- realboard[handicap13[i].x][handicap13[i].y] = black ;
- }
- }
- if (size==19)
- {
- if ( (handicap==5) ||
- (handicap==7) ||
- (handicap==9) )
- {
- temphandicap = handicap - 1 ;
- realboard[10][10] = black ;
- }
- else
- {
- temphandicap = handicap ;
- }
- for (i=0;i<temphandicap;i++)
- {
- realboard[handicap19[i].x][handicap19[i].y] = black ;
- }
- }
- }
-
- /*
- * Function: postype
- *
- * Description: Returns a value that indicates what sort of position (x,y)
- * is eg top left corner, right side etc
- *
- *
- * Globals affected: none
- *
- */
- POSTYPE
- postype(x,y)
- COORD x,y ;
- {
- if (x==1)
- {
- if (y==1)
- {
- return(topleft) ;
- }
- else if (y==size)
- {
- return(bottomleft) ;
- }
- else
- {
- return(leftside) ;
- }
- }
- else if (x==size)
- {
- if (y==1)
- {
- return(topright) ;
- }
- else if (y==size)
- {
- return(bottomright) ;
- }
- else
- {
- return(rightside) ;
- }
- }
- else if (y==1)
- {
- return(topside) ;
- }
- else if (y==size)
- {
- return(bottomside) ;
- }
- else
- {
- return(middle) ;
- }
- }
-
- /*
- * Function: starpoint()
- *
- * Description: Returns TRUE if x,y is a handicap point. This function is unused
- * in this file but may be used by the terminal interface driver.
- *
- *
- * Globals affected: none
- *
- */
- BOOLEAN
- starpoint(x,y)
- char x,y ;
- {
- BOOLEAN notfound ;
- int indx;
-
- notfound = TRUE ;
- indx = 0 ;
-
- if (size==9)
- {
- while ( (indx < 5) && notfound )
- {
- if ( (handicap9[indx].x==x) &&
- (handicap9[indx].y==y) )
- {
- notfound = FALSE ;
- }
- else
- {
- indx ++ ;
- }
- }
- }
-
- else
- if (size==13)
- {
- while ( (indx < 5) && notfound )
- {
- if ( (handicap13[indx].x==x) &&
- (handicap13[indx].y==y) )
- {
- notfound = FALSE ;
- }
- else
- {
- indx ++ ;
- }
- }
- }
-
- else
- if (size==19)
- {
- if ( (x==10) && (y==10) )
- {
- notfound = FALSE ;
- }
-
- while ( (indx < 8) && notfound )
- {
- if ( (handicap19[indx].x==x) &&
- (handicap19[indx].y==y) )
- {
- notfound = FALSE ;
- }
- else
- {
- indx ++ ;
- }
- }
- }
-
-
- if (notfound)
- {
- return(FALSE) ;
- }
- else
- {
- return(TRUE) ;
- }
-
- }
-
- /*
- * Function: placestone()
- *
- * Description: Calls the terminal interface routines to draw the correct
- * colour of stone.
- *
- *
- * Globals affected: none
- *
- */
- placestone(x,y,n)
- COORD x,y ;
- MOVENUMBER n ;
- {
- COLOUR colour ;
-
-
-
- colour = stonecolour(n) ;
-
- if (colour==EMPTY)
- {
- drawempty(x,y) ;
- }
- else
- {
- drawstone(x,y,n,colour) ;
- }
-
- }
-
- /*
- * Function: initialiseflags()
- *
- * Description: Sets grid, numbers and lastmove flags so that they
- * are displayed. Called at the begining of every file.
- *
- *
- * Globals affected: flag[]
- *
- */
- void
- initialiseflags()
- {
- flag[NUMBERS] = on ;
- flag[GRID] = on ;
- flag[LASTMOVE] = on ;
- }
-
- /*
- * Function: zeroboard()
- *
- * Description: Initialises the realboard before a game.
- *
- *
- * Globals affected: komove, realboard, blackcaptured, whitecaptured
- *
- */
- zeroboard()
- {
- COORD i,j ;
-
- blackcaptured = 0 ;
- whitecaptured = 0 ;
-
- komove.x = 0 ;
- komove.y = 0 ;
-
- lastmovestring[0] = 0 ;
-
- for (i=1;i<=size;i++)
- for (j=1;j<=size;j++)
- realboard[i][j] = 0 ;
- }
-
- /*
- * Function: resetgame()
- *
- * Description: Called when there has been a reconfigure.
- *
- *
- *
- * Globals affected: size, handicap, rawindex, filename[]
- *
- */
- resetgame(s,h)
- char s,h ;
- {
- int indx ;
-
- zeroboard() ;
-
- if ( s > (MAX-1) )
- s = (MAX-1) ; /* (MAX-1) is max size of board */
-
- size = s ;
-
- if ( ( size==9 || size==13 || size==19 ) &&
- ( h < 10 && h > 1 ) )
- {
- if ( ( size==9 || size==13 ) && ( h > 5 ) )
- handicap = 5 ;
- else
- handicap = h ;
- }
- else
- {
- handicap = 0 ;
- }
-
- reconfigure() ;
- setstonecolour() ;
- putstarpoints() ;
- currentmove = 1 ;
-
- if (flag[STEPPING]==off)
- {
- /* So that files written away
- * dont include all the previous
- * stuff, zero rawindex. However
- * this routine can also be called
- * during 'going to a move' hence
- * this zeroing is conditional
- */
-
- if (rawindex>0) /* free the memory previously allocated */
- {
- for ( indx=0 ; indx < rawindex ; indx++ )
- free( raw[indx] ) ;
- }
-
- rawindex = 0 ;
- filename[0] = 0 ;
- lastreconfigure = 0 ;
- steppingindex = 0 ;
-
- }
- else
- {
- lastreconfigure = steppingindex ;
- }
-
- refreshmenu() ;
-
- erasescreen() ;
- drawboard();
- }
-
- /*
- * Function: samecolour
- *
- * Description: Returns TRUE if the stone is of the specified colour.
- *
- *
- * Globals affected: none
- *
- */
- BOOLEAN
- samecolour(s,c)
- MOVENUMBER s ; /* number of stone to be checked */
- COLOUR c ; /* colour to be checked against */
- {
- COLOUR stonescolour ;
- BOOLEAN retval ;
-
- if (s==0)
- retval = FALSE ;
- else
- {
-
- if ( ((handicap!=0) && ((s%2)==0)) ||
- ((handicap==0) && ((s%2)!=0)) )
- stonescolour = black ;
- else
- stonescolour = white ;
-
- if (stonescolour==c)
- retval = TRUE ;
- else
- retval = FALSE ;
- }
-
- return(retval) ;
- }
-
- /*
- * Function: notindeadstones
- *
- * Description: Returns TRUE if (x,y) is not in the array deadstones[]
- *
- *
- * Globals affected: none
- *
- */
- BOOLEAN
- notindeadstones(x,y)
- COORD x,y ;
- {
- int index ;
- BOOLEAN retval ;
-
- retval = TRUE ;
- index = 0 ;
-
- while ( (index < checking) && (retval==TRUE) )
- {
- index++ ;
-
- if ( (deadstones[index].x==x) &&
- (deadstones[index].y==y) )
- retval = FALSE ;
-
- }
-
- return(retval) ;
- }
-
- /*
- * Function: checksurrounded
- *
- * Description: (x,y) is the point neighbouring a stone of colour c. If (x,y)
- * is occupied then there is a chance that c could be captured,
- * if (x,y) is of the same colour and not already in deadstones[]
- * then put this in the list to continue the search.
- *
- * Globals affected: checking, deadstones[]
- *
- */
- BOOLEAN
- checksurrounded(x,y,b,c)
- COORD x,y ;
- MOVENUMBER b[MAX][MAX] ;
- COLOUR c ;
- {
- BOOLEAN retval ;
-
-
- if (b[x][y]==0)
- {
- retval = FALSE ;
- }
- else
- {
- retval = TRUE ;
- if (samecolour(b[x][y],c))
- {
- if (notindeadstones(x,y))
- {
- checking++ ;
- deadstones[checking].x = x ;
- deadstones[checking].y = y ;
- }
- }
- }
-
- return(retval) ;
- }
-
- /*
- * Function: checkcapture
- *
- * Description: Searches a whole group of 'colour' to see if it is captured.
- *
- * 'captured' is the number already captured ie from deadstones[1]
- * to deadstones[captured] are the stones already captured by this
- * latest move (note the stones have not yet been taken off the
- * board).
- * From deadstones[captured] to deadstones[checking] is a group of
- * stones that is yet to be decided if alive or not.
- *
- * Globals affected: captured, checking
- *
- */
- checkcapture(b,colour)
- MOVENUMBER b[MAX][MAX] ;
- COLOUR colour ;
- {
- COORD x,y ;
- int index ;
- BOOLEAN surrounded ;
- POSTYPE thispos ;
-
- index = 0 ;
- surrounded = TRUE ;
-
- while ( (index<(checking-captured)) && (surrounded) )
- {
-
- index++ ;
- x = deadstones[captured+index].x ;
- y = deadstones[captured+index].y ;
-
- thispos = postype(x,y) ;
-
- surrounded = FALSE ;
-
- switch((int)thispos)
- {
- case topleft : if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case topside : if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case topright : if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case leftside : if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case middle : if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case rightside :if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y+1,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case bottomleft :if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case bottomside :if (checksurrounded(x+1,y,b,colour))
- if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- case bottomright :if (checksurrounded(x-1,y,b,colour))
- if (checksurrounded(x,y-1,b,colour))
- surrounded = TRUE ;
- break ;
-
- } /* end switch */
- }
-
- if (surrounded)
- captured = checking ;
- else
- checking = 0 ;
- }
-
- /*
- * Function: saveboard
- *
- * Description: Saves the variables used for an 'undo'
- *
- *
- *
- * Globals affected: undoboard[][], savedblackcaptured, savedwhitecaptured,
- * savedcurrentmove, savedkomove,
- * practiceboard[][], savednextpracticestone,
- * savedlastmovestring, undorawindex, undopracticeboard[][]
- */
- saveboard()
- {
-
- if (flag[PRACTICE]==off)
- {
- copyboard(realboard,undoboard) ;
- savedblackcaptured = blackcaptured ;
- savedwhitecaptured = whitecaptured ;
- savedcurrentmove = currentmove ;
- savedkomove = komove ;
- strcpy( savedlastmovestring, lastmovestring ) ;
-
- if (flag[STEPPING]==off)
- undorawindex = rawindex ;
- else
- undorawindex = steppingindex ;
- }
- else
- {
- copyboard(practiceboard,undopracticeboard) ;
- savednextpracticestone = nextpracticestone ;
- savedkomove = komove ;
- }
- }
-
- /*
- * Function: playstone
- *
- * Description: Updates the movenumers if not practicing and the relevant
- * board passed as a parameter then calls placestone() to draw
- * it on the screen.
- *
- * Globals affected: currentmove, nextpracticestone, lastmovestring
- *
- */
- playstone(x,y,b)
- COORD x,y;
- MOVENUMBER b[MAX][MAX] ;
- {
- MOVENUMBER movenumber ;
-
-
- if (flag[PRACTICE]==off)
- {
- movenumber = currentmove ;
- currentmove++ ;
- b[x][y] = movenumber ;
-
- converttostring(x,y,lastmovestring) ;
- displaylastmove(lastmovestring) ;
- }
- else
- {
- b[x][y] = nextpracticestone ;
- movenumber = nextpracticestone ;
-
- if (nextpracticestone==black)
- {
- nextpracticestone=white ;
- }
- else
- {
- nextpracticestone=black ;
- }
-
- }
-
-
-
- placestone(x,y,movenumber) ;
-
- }
-
- /*
- * Function: removecaptured
- *
- * Description: For all the stone referenced in deadstones[], zero the
- * board passed as a parameter, then call placestone() to
- * remove the stone from the screen.
- *
- * Globals affected: none
- *
- */
- void
- removecaptured(b)
- MOVENUMBER b[MAX][MAX] ;
- {
- int index ;
- COORD x,y ;
-
- for (index=1;index<=captured;index++)
- {
- x = deadstones[index].x ;
- y = deadstones[index].y ;
- b[x][y] = 0 ;
- placestone(x,y,0) ;
- }
- }
-
- /*
- * Function: docheck
- *
- * Description: If there is a stone at (x,y) and has the same colour as c,
- * then store it in deadstones[] and search for all
- * others of the same colour adjoining this one.
- *
- *
- * Globals affected: checking, deadstones[]
- *
- */
- docheck(x,y,b,c)
- COORD x,y ;
- MOVENUMBER b[MAX][MAX] ;
- COLOUR c ;
- {
- if (samecolour(b[x][y],c))
- {
- if (notindeadstones(x,y))
- {
- checking = captured + 1 ;
- deadstones[checking].x = x ;
- deadstones[checking].y = y ;
- checkcapture(b,c) ;
- }
- }
- }
-
- /*
- * Function: store()
- *
- * Description: Allocates memory and copies the string to that memory then
- * assigns the next element in raw[] to reference the string
- *
- *
- * Globals affected: raw[], rawindex
- *
- */
- void
- store(s)
- char *s ;
- {
-
- if (rawindex==MAXRAW)
- {
- errorprint("raw buffer full") ;
- }
- else
- {
-
- raw[rawindex] = malloc((unsigned)strlen(s)) ;
- if (raw[rawindex]==NULL)
- {
- errorprint("No memory") ;
- }
- else
- {
- strcpy(raw[rawindex],s) ;
- rawindex++ ;
- }
- }
-
- }
-
- /*
- * Function: storenewgame
- *
- * Description: Writes into raw[] the new configuration
- *
- *
- *
- * Globals affected: none
- *
- */
- storenewgame(s,h)
- char s,h ;
- {
- char sizestr[6] ;
- char handicapstr[2] ;
-
- sizestr[0] = 0 ;
- sprintf( sizestr, "%d ", s) ;
-
- handicapstr[0] = 0 ;
- sprintf( handicapstr, "%d", h) ;
-
- strcat( sizestr, handicapstr ) ;
- strcat( sizestr, "\n" ) ;
-
- store( sizestr ) ;
- }
-
- /*
- * Function: writefileaway
- *
- * Description: prompts the player for a file name if it is the same as the
- * one entered for 'reading' last time then append from writeindex
- * to rawindex in raw[] to the end of that file, else write the
- * whole of raw[] out to the file and save the filename so that
- * it can be appended to next time.
- *
- * Globals affected: filename, tempfilename, fptr
- *
- */
- writefileaway()
- {
- int indx ;
-
- getfilename(tempfilename) ;
-
- if (tempfilename[0]!=0)
- {
- if (strcmp(filename,tempfilename)==0)
- {
- /* names are the same so append */
- fptr = fopen(directoryplus(filename),"a+") ;
- if (fptr==(FILE *)NULL)
- {
- errorprint ("unable to open file") ;
- }
- else
- {
- displaystring("appending") ;
- for (indx=writeindex;indx<rawindex;indx++)
- {
- fputs(raw[indx],fptr) ;
- }
-
- fclose(fptr) ;
- clearpromptline() ;
- writeindex = rawindex ;
- }
- }
- else
- {
- /* names different so write */
- fptr = fopen(directoryplus(tempfilename),"w") ;
- if (fptr==(FILE *)NULL)
- {
- errorprint ("unable to open file") ;
- }
- else
- {
- displaystring("writing") ;
- for (indx=0;indx<rawindex;indx++)
- {
- fputs(raw[indx],fptr) ;
- }
-
- fclose(fptr) ;
- clearpromptline() ;
- writeindex = rawindex ;
- strcpy (filename,tempfilename) ;
- }
- }
- }
- else
- {
- clearpromptline() ;
- }
-
- }
-
- /*
- * Function: passmove()
- *
- * Description: A player has passed, set relevant data accordingly.
- *
- *
- * Globals affected: currentmove, komove, nextpracticestone
- * lastmovestring[]
- */
- void
- passmove()
- {
-
- saveboard() ;
-
- if (flag[PRACTICE]==off)
- {
- currentmove ++ ;
- komove.x = 0 ;
- komove.y = 0 ;
-
- converttostring(0,0,lastmovestring) ;
- displaylastmove(lastmovestring) ;
- refreshmenu() ;
- }
- else
- {
- if ( nextpracticestone==black)
- {
- nextpracticestone = white ;
- }
- else
- {
- nextpracticestone = black ;
- }
- komove.x = 0 ;
- komove.y = 0 ;
- }
- }
-
- /*
- * Function: domove
- *
- * Description: Play a move on board b[][] at (x,y), perform any capturing and
- * illegal move checking necessary.
- * If x and y are both 0, this is treated as a 'pass'.
- * Return a boolean indicating whether it was a legal move or not.
- *
- * Globals affected: captured, checking, komove
- *
- */
- BOOLEAN
- domove(x,y,b)
- COORD x,y ;
- MOVENUMBER b[MAX][MAX] ;
- {
- COLOUR thisstonecolour, oppositecolour ;
- POSTYPE thispos ;
- BOOLEAN legalmove ;
-
- if ( (x==0) && (y==0) )
- {
- passmove() ;
- legalmove = TRUE ;
- }
- else
- {
- /* Basic checks */
- if ( (b[x][y]!=0) || /* can't play on top of another stone */
- (x<1) || /* out of range */
- (x>size) ||
- (y<1) ||
- (y>size) )
- {
- clearpromptline() ;
- displaystring("Must play on one of the vacant points") ;
- legalmove = FALSE ;
- }
-
- else
- {
-
- if (flag[PRACTICE]==off)
- {
- thisstonecolour = stonecolour(currentmove) ;
- }
- else
- {
- if (nextpracticestone==black)
- {
- thisstonecolour = black ;
- }
- else
- {
- thisstonecolour = white ;
- }
- }
-
-
- if (thisstonecolour==black)
- oppositecolour = white ;
- else
- oppositecolour = black ;
-
- saveboard() ;
- b[x][y] = thisstonecolour ; /*put the stone in temporarily*/
-
- captured = 0 ;
- checking = 0 ;
-
- thispos = postype(x,y) ;
-
- /* See if any opponents' stones have been captured */
-
- switch((int)thispos)
- {
- case topleft : docheck(x+1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- break ;
-
- case topside : docheck(x+1,y,b,oppositecolour);
- docheck(x-1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- break ;
-
- case topright : docheck(x-1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- break ;
-
- case rightside: docheck(x-1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- case middle : docheck(x+1,y,b,oppositecolour);
- docheck(x-1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- case leftside : docheck(x+1,y,b,oppositecolour);
- docheck(x,y+1,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- case bottomleft:docheck(x+1,y,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- case bottomside:docheck(x+1,y,b,oppositecolour);
- docheck(x-1,y,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- case bottomright:docheck(x-1,y,b,oppositecolour);
- docheck(x,y-1,b,oppositecolour);
- break ;
-
- default : errorprint("Illegal postype in domove()");
- break ;
-
- } /* end switch */
-
- if (captured==0)
- {
- /* No opponents' stones taken so check the
- * group formed by this move to see if it
- * is dead.
- */
- docheck(x,y,b,thisstonecolour) ;
-
- if (captured==0)
- {
- playstone(x,y,b) ;
- komove.x = 0 ;
- komove.y = 0 ;
- legalmove = TRUE ;
- }
- else
- {
- clearpromptline() ;
- displaystring("Cannot play a suicidal move") ;
- /* suicidal move */
- legalmove = FALSE ;
- b[x][y] = 0 ;
- }
- }
- else if (captured==1)
- {
- /* Simplistic Ko Algorithm:
- * If last move only took one stone
- * and this move is in the same
- * position and it only takes one
- * then this is ko.
- */
- if ( (komove.x==x) &&
- (komove.y==y) )
- {
- /* ko */
- clearpromptline() ;
- displaystring("Must play elsewhere first before re-taking : the rule of ko") ;
- b[x][y] = 0 ;
- legalmove = FALSE ;
- }
- else
- {
- komove.x = deadstones[1].x ;
- komove.y = deadstones[1].y ;
- playstone(x,y,b) ;
- removecaptured(b) ;
-
- if (flag[PRACTICE]==off)
- {
- if (oppositecolour==black)
- blackcaptured += captured ;
- else
- whitecaptured += captured ;
- displaycaptured() ;
- }
-
- legalmove = TRUE ;
- }
- } /* end if captured = 1 */
- else
- {
- playstone(x,y,b) ;
- removecaptured(b) ;
-
- if (flag[PRACTICE]==off)
- {
- if (oppositecolour==black)
- blackcaptured += captured ;
- else
- whitecaptured += captured ;
- displaycaptured() ;
- }
-
- komove.x = 0 ;
- komove.y = 0 ;
- legalmove = TRUE ;
- } /* end if captured > 1 */
-
- } /* end if basic checks */
-
- } /* end if pass */
-
- return(legalmove) ;
- }
-
- /*
- * Function: translateascii
- *
- * Description: Translate the character passed which represents the East-West
- * grid reference into the index 1 to 19, return this value.
- *
- *
- * Globals affected: none
- *
- */
- char
- translateascii(c)
- char c ;
- {
- char retval ;
-
- if ( (c>='a') && (c<='h') )
- {
- retval = c-'a'+1 ;
- }
-
- if (c=='i') retval=0;
-
- if ( (c>='j') && (c<='t') )
- {
- retval = c-'a' ;
- }
-
- if ( (c>='A') && (c<='H') )
- {
- retval = c-'A'+1 ;
- }
-
- if (c=='I') retval=0;
-
- if ( (c>='J') && (c<='T') )
- {
- retval = c-'A' ;
- }
-
-
- return(retval) ;
- }
-
- /*
- * Function: translateraw
- *
- * Description: Return a value indicating what sort of 'text' was in the
- * raw line passed as a parameter, returns a string and/or values
- * found in the raw line if necessary eg newgame means x will
- * be the size, y will be the handicap and s will have any
- * comment that accompanies the new game.
- * nullraw may or may not have text associated with it.
- *
- * Globals affected: none
- *
- */
- RAWTYPE
- translateraw (r,x,y,s,skip)
- char *r,*s ; /* r is a pointer to the raw string */
- /* s is a pointer to returned text */
- char *x,*y ; /* x and y are retruned values */
- BOOLEAN *skip ;
- {
-
-
- /* Table of character collecting states */
- /* The number shown in th etable represents the next collecting state */
- /* WS=white space, E=error, X=exit */
- /* Alpha Numeric WS '!' '|' '#' */
- #define COLLECTING 0 /* 5 1 0 4 X 3 */
- #define SIZE 1 /* E 1 2 E E E */
- #define HANDICAP 2 /* E 2 2 E X 3 */
- #define COMMENT 3 /* 3 3 3 3 X 3 */
- #define CONTROL 4 /* 4 4 X 4 4 4 */
- #define XMOVE 5 /* E 6 6 E E E */
- #define YMOVE 6 /* E 6 6 E X 3 */
-
- int index ; /* index into r */
- RAWTYPE retval ;
- BOOLEAN oktoexit ;
- unsigned char state ;
- int count ; /* number of chars in s already */
- int n ; /* used for building up decimal numbers */
-
- *s = 0 ;
- retval = nullraw ;
- oktoexit = FALSE ;
- index = 0 ;
-
- *x = 0 ;
- *y = 0 ;
-
- *skip = FALSE ;
-
- state = COLLECTING ;
-
- while ( (r[index]!=0) && (!oktoexit) )
- {
- /* first check for the 'pass' string */
- if ( (strncmp(&r[index],"pass",4)==0) &&
- (retval==nullraw) &&
- (state==COLLECTING) )
- {
- *x = 0 ;
- *y = 0 ;
- retval = amove ;
- index += 4 ;
- }
-
- switch (r[index])
- {
- case ' ' :
- case '\t' :
- case '\n' :
- switch (state)
- {
- case COLLECTING :
- break ;
- case SIZE :
- state = HANDICAP ;
- *x = n ;
- n = 0 ;
- break ;
- case HANDICAP :
- break ;
- case COMMENT :
- s[count++] = r[index] ;
- break ;
- case CONTROL :
- oktoexit = TRUE ;
- retval = control ;
- *skip = TRUE ;
- break ;
- case XMOVE :
- state = YMOVE ;
- n = 0 ;
- break ;
- case YMOVE :
- break ;
- default : break ;
- }
- break ;
-
- case '!' :
- switch (state)
- {
- case COLLECTING :
- count = 0 ;
- state = CONTROL ;
- break ;
- case SIZE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case HANDICAP :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case COMMENT :
- s[count++] = r[index] ;
- break ;
- case CONTROL :
- s[count++] = r[index] ;
- break ;
- case XMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case YMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- default : break ;
- }
- break ;
-
- case '|' :
- switch (state)
- {
- case COLLECTING :
- oktoexit = TRUE ;
- *skip = TRUE ;
- break ;
- case SIZE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case HANDICAP :
- retval = newgame ;
- oktoexit = TRUE ;
- *skip = TRUE ;
- *y = n ;
- break ;
- case COMMENT :
- oktoexit = TRUE ;
- *skip = TRUE ;
- break ;
- case CONTROL :
- s[count++] = r[index] ;
- break ;
- case XMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case YMOVE :
- retval = amove ;
- *y = size - n + 1 ;
- oktoexit = TRUE ;
- *skip = TRUE ;
- break ;
- default : break ;
- }
- break ;
-
- case '#' :
- switch (state)
- {
- case COLLECTING :
- count = 0 ;
- state = COMMENT ;
- break ;
- case SIZE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case HANDICAP :
- count = 0 ;
- retval = newgame ;
- state = COMMENT ;
- *y = n ;
- break ;
- case COMMENT :
- s[count++] = r[index] ;
- break ;
- case CONTROL :
- s[count++] = r[index] ;
- break ;
- case XMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case YMOVE :
- count = 0 ;
- retval = amove ;
- *y = size - n + 1 ;
- state = COMMENT ;
- break ;
- default : break ;
- }
- break ;
-
- default :
- if ( r[index]>='0' && r[index]<='9' )
- switch (state)
- {
- case COLLECTING :
- state = SIZE ;
- n = r[index] - '0' ;
- break ;
- case SIZE :
- n = n*10 + r[index] - '0' ;
- break ;
- case HANDICAP :
- n = r[index] - '0' ;
- break ;
- case COMMENT :
- s[count++] = r[index] ;
- break ;
- case CONTROL :
- s[count++] = r[index] ;
- break ;
- case XMOVE :
- state = YMOVE ;
- n = r[index] - '0' ;
- break ;
- case YMOVE :
- n = n*10 + r[index] - '0' ;
- break ;
- default : break ;
- }
- else
- switch (state)
- {
- case COLLECTING :
- if ( ( r[index]>='a' && r[index]<='z' ) ||
- ( r[index]>='A' && r[index]<='Z' ) )
- {
- state = XMOVE ;
- *x = translateascii(r[index]) ;
- }
- break ;
- case SIZE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case HANDICAP :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case COMMENT :
- s[count++] = r[index] ;
- break ;
- case CONTROL :
- s[count++] = r[index] ;
- break ;
- case XMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- case YMOVE :
- retval = rawerror ;
- oktoexit = TRUE ;
- break ;
- default : break ;
- }
- break ;
-
-
- } /* end switch on r[index] */
-
- index++ ;
- }
-
-
- if ( retval != rawerror)
- {
-
- if ( state==SIZE || state==XMOVE)
- retval = rawerror ;
-
- if ( state==HANDICAP )
- {
- *y = n ;
- retval = newgame ;
- }
-
- if ( state==YMOVE )
- {
- *y = size - n + 1 ;
- retval = amove ;
- }
-
- if ( state==COMMENT || state==CONTROL )
- s[count] = 0 ;
-
- /* skip over any blank lines in the input */
- if ( (retval==nullraw) && (s[0]==0) )
- *skip = TRUE ;
- }
-
- return(retval) ;
- }
-
- /*
- * Function: errorat()
- *
- * Description: The file read in contains an error at line n, display
- * the appropriate message.
- *
- * Globals affected: none
- *
- */
-
- errorat( msg, n )
- char msg[MAXLINELENGTH] ;
- int n ;
- {
- char str[3] ;
- char total[MAXLINELENGTH+3] ;
-
-
- str[0] = '\0' ;
- sprintf( str, "%d", n ) ;
-
- total[0] = 0 ;
- strcat( total, msg ) ;
- strcat( total, str ) ;
-
- errorprint( total ) ;
- }
-
- /*
- * Function: readline()
- *
- * Description: Reads in a line from file pointed to by fptr,
- * allocates the memory in store it and then copies the
- * line into raw[].
- *
- * If EOF or no memory left then returns FALSE.
- *
- * Is responsible for printing an error message if one happens
- *
- * Globals affected: raw[], rawindex
- *
- */
- BOOLEAN
- readline()
- {
- char line[MAXLINELENGTH] ;
- BOOLEAN retval ;
-
- retval = TRUE ;
-
- if (rawindex==MAXRAW)
- {
- errorprint("raw buffer full") ;
- retval = FALSE ;
- }
- else
- {
-
- if ( fgets( line, MAXLINELENGTH, fptr ) != NULL )
- {
- /* fgets reads up to MAXLINELENGTH-1 and if it hasnt found a
- * newline puts a '\0' at MAXLINELENGTH position.
- * (fgets leaves the newline at the end of a string)
- */
-
- if ( ( strlen(line)==MAXLINELENGTH-1) &&
- ( line[MAXLINELENGTH-2]!='\n') )
- {
- errorat("Input exceeds '80 char + newline' limit at line ", rawindex+1 ) ;
- retval = FALSE ;
- }
-
- raw[rawindex] = malloc((unsigned)strlen(line)) ;
-
- if (raw[rawindex]==NULL)
- {
- errorprint("No memory") ;
- retval = FALSE ;
- }
- else
- {
- strcpy( raw[rawindex], line ) ;
- rawindex++ ;
- }
- }
- else
- {
- /* EOF */
- retval = FALSE ;
- }
- }
-
- return(retval) ;
- }
-
- /*
- * Function: toggleflag
- *
- * Description:
- *
- *
- *
- * Globals affected: flag[]
- *
- */
- void
- toggleflag(f)
- char f ;
- {
- if (flag[f]==off)
- flag[f]=on ;
- else
- flag[f]=off ;
-
- refreshmenu() ;
- }
-
- /*
- * Function: docontrol
- *
- * Description: Perform the control specified in the string passed as a
- * parameter
- *
- *
- * Globals affected: none
- *
- */
- void
- docontrol(str)
- char *str ;
- {
- if ( strcmp(str,"numbers") == 0 )
- {
- toggleflag(NUMBERS) ;
- }
-
- if ( strcmp(str,"grid") == 0 )
- {
- toggleflag(GRID) ;
- }
-
- if ( strcmp( str, "lastmove" ) == 0 )
- {
- toggleflag(LASTMOVE) ;
- }
-
- if ( strcmp(str,"clear") == 0 )
- {
- erasescreen() ;
- }
- }
-
- /*
- * Function: translateline
- *
- * Description: Performs the actions specified in the text of str,
- * returns TRUE if if the line contained a legal move.
- *
- * Globals affected: size, handicap, currentmove
- *
- */
- BOOLEAN
- translateline(str,text,skip)
- char *str ;
- char text[MAXLINELENGTH] ;
- BOOLEAN *skip ;
- {
- char x,y ;
-
- BOOLEAN ret_val ;
-
- ret_val = TRUE ;
-
-
-
- switch((int)translateraw(str,&x,&y,text,skip))
- {
- case amove: if (flag[PRACTICE]==off)
- ret_val = domove((COORD)x,(COORD)y,realboard) ;
- else
- ret_val = domove((COORD)x,(COORD)y,practiceboard) ;
- break ;
-
- case newgame: resetgame(x,y) ;
- ret_val = TRUE ;
- break ;
-
- case control: docontrol(text) ;
- ret_val = TRUE ;
- text[0] = 0 ; /* zero the text so that it
- * doesn't get mistaken for
- * a comment in readastep()
- */
- break ;
-
- case nullraw : break ;
-
- case rawerror : ret_val = FALSE ;
- break ;
-
- default: errorprint("translateline error") ;
- ret_val = FALSE ;
- break ;
- }
-
- return(ret_val);
- }
-
- /*
- * Function: readin
- *
- * Description: Reads in a whole file, performing the moves.
- *
- *
- * Globals affected: writeindex
- *
- */
- readin(fn)
- char fn[] ;
- {
- char text[MAXLINELENGTH] ;
- BOOLEAN skip ;
- BOOLEAN line_ok ;
-
- rawindex = 0 ;
- writeindex = 0 ;
-
- fptr = fopen(directoryplus(fn),"r") ;
- if (fptr==(FILE *)NULL)
- {
- errorprint("unable to open file") ;
- return ;
- }
-
- initialiseflags() ;
-
- displaystring("reading") ;
-
- line_ok = TRUE ;
-
- while ( readline()==TRUE && line_ok==TRUE )
- {
- line_ok = translateline( raw[rawindex-1], text, &skip ) ;
- }
-
- if ( line_ok != TRUE )
- errorat( ILLEGALAT, rawindex ) ;
-
-
- writeindex = rawindex ;
-
- fclose(fptr) ;
-
- clearpromptline() ;
-
- }
-
- /*
- * Function: stripnewline()
- *
- * Description: If there is a newline char '\n' at the end of s then replace
- * it with a null '\0'
- *
- *
- * Globals affected: none
- *
- */
- stripnewline(s)
- char s[] ;
- {
- if (s[strlen(s)-1]=='\n')
- s[strlen(s)-1] = '\0' ;
- }
-
- /*
- * Function: gotoaline()
- *
- * Description: String passed is the index into raw[] that the player
- * wishes to end up at.
- *
- *
- * Globals affected:
- *
- */
- void
- gotoaline(s)
- char s[MAXLINELENGTH] ;
- {
- MOVENUMBER n ;
- char text[MAXLINELENGTH] ;
- BOOLEAN skip ;
-
- n = (MOVENUMBER)atoi(s) ;
-
- if ( ( n != steppingindex ) && ( n != 0 ) )
- {
- if ( n < (steppingindex+1) )
- steppingindex = 0 ;
-
- while ( ( steppingindex < rawindex ) &&
- ( steppingindex < n ) )
- {
- (void)translateline(raw[steppingindex],
- text,
- &skip) ;
- steppingindex++ ;
- refreshmenu() ;
- }
- }
-
- }
-
- /*
- * Function: gotoamove
- *
- * Description: Re-reads a file stored in raw[], performing the moves up to
- * a move number or move specified in the parameter.
- *
- *
- * Globals affected: currentmove, steppingindex
- *
- */
- gotoamove(s)
- char s[MAXLINELENGTH] ;
- {
- int indx ;
- char text[MAXLINELENGTH] ;
- BOOLEAN skip ;
- char x,y ;
-
- /* Use translateraw() to decide whether the parameter is a movenumber
- * or an actual move, (using 'newgame' is a dirty trick but it works)
- */
-
- switch( (int)translateraw( s, &x, &y, text, &skip ) )
- {
- case amove :
- stripnewline(s) ;
-
- /* If the first is a space or a tab (the
- * only allowable white spaces) then shift it down
- */
- if (s[0]==' ' || s[0]=='\t')
- {
- for (indx=0 ; indx<=strlen(s) ; indx++ )
- s[indx] = s[indx+1] ;
- }
-
- /* convert the ascii letter in the coordinates
- * to upper case, this works even if it is already
- * in upper case.
- */
- s[0] ^= 0x20 ;
-
- steppingindex = lastreconfigure ;
-
- while ( ( steppingindex < rawindex ) &&
- ( strcmp(lastmovestring,s)!=0 ) )
- {
- (void)translateline(raw[steppingindex], text, &skip) ;
- steppingindex++ ;
- }
- break ;
-
- case newgame :
- /* ie goto a move number, x is the move number */
-
- if ( x < currentmove )
- steppingindex = lastreconfigure ;
-
- if ( x != currentmove )
- {
- do
- {
- (void)translateline(raw[steppingindex],
- text,
- &skip) ;
- steppingindex++ ;
- }
- while ( ( steppingindex < rawindex ) &&
- ( currentmove <= x ) ) ;
- }
- break ;
-
- default :
- /* ignore errors as player may just have made a
- * mistake in requesting goto
- */
- break ;
-
- }
-
- }
-
- /*
- * Function: readastep()
- *
- * Description: Translate the next line in raw[], performs the action and
- * displays any comment that goes with the text.
- * If the text was a 'skip' then continue reading until the
- * next non skip.
- *
- * Globals affected: size, handicap, currentmove, steppingindex
- *
- */
- void
- readastep()
- {
-
- char text[MAXLINELENGTH] ;
- BOOLEAN skip ;
- BOOLEAN line_ok ;
-
- if (steppingindex>=rawindex)
- {
- clearpromptline() ;
- displaystring("End of file") ;
- }
- else
- {
-
- skip = TRUE ;
-
- line_ok = TRUE ;
-
- while ( ( skip ) && ( steppingindex < rawindex ) )
- {
- line_ok = translateline(raw[steppingindex],text,&skip) ;
-
- if (line_ok==TRUE)
- {
- if (text[0]!=0)
- {
- clearpromptline() ;
- displaystring(text) ;
- }
- }
- else
- {
- errorat( ILLEGALAT, steppingindex+1 ) ;
- }
-
- steppingindex++ ;
- refreshmenu() ;
-
- } /* end while */
-
- }
-
- }
-
- /*
- * Function: startstepping()
- *
- * Description: Prompts the player for a file name, if it is the same as
- * the one read in (ie text is already in raw[]) then proceed to
- * perform the first step, else read in the whole file into
- * raw[] without translating it, then perform the first step.
- *
- * Globals affected: rawindex, raw[], steppinindex, flag[STEPPING]
- *
- */
- startstepping()
- {
-
- filename[0] = 0 ;
-
- getfilename(tempfilename) ;
-
- if ( tempfilename[0]!=0 )
- {
- fptr = fopen(directoryplus(tempfilename),"r") ;
- if (fptr==(FILE *)NULL)
- {
- errorprint("unable to open file") ;
- }
- else
- {
- initialiseflags() ;
-
- rawindex = 0 ;
-
- displaystring("reading") ;
-
- while ( readline() == TRUE ) ;
-
- fclose(fptr) ;
-
- clearpromptline() ;
-
- steppingindex = 0 ;
- flag[STEPPING] = on ;
- refreshmenu() ;
- readastep() ;
- }
- }
- }
-
- /*
- * Function: setstonecolour
- *
- * Description: This determines what value the colours black and white will
- * have. If there is no handicap then white will be even move
- * numbers and black odd, else the other way around.
- *
- * Globals affected: none
- *
- */
- setstonecolour()
- {
- if (handicap==0)
- {
- black = 1 ;
- white = 2 ;
- }
- else
- {
- black = 2 ;
- white = 1 ;
- }
- }
-
- /*
- * Function: removedifferences
- *
- * Description: Restores old board to look like new board
- *
- *
- * Globals affected: none
- *
- */
- removedifferences(old,new)
- MOVENUMBER old[MAX][MAX] ;
- MOVENUMBER new[MAX][MAX] ;
- {
- COORD i,j ;
-
- for (i=1;i<=size;i++)
- for (j=1;j<=size;j++)
- if (old[i][j]!=new[i][j])
- {
- placestone(i,j,new[i][j]) ;
- old[i][j] = new[i][j] ;
- }
- }
-
- /*
- * Function: convertandstore
- *
- * Description: Converts the move passed in 'internal format' into a string
- * and stores in it raw[]
- *
- *
- * Globals affected: none
- *
- */
- convertandstore(x,y)
- COORD x,y ;
- {
- char str[6] ;
-
- converttostring( x, y, str ) ;
-
- strcat( str, "\n") ;
-
- store( str ) ;
- }
-
- /*
- * Function: converttostring
- *
- * Description: Converts the move in (x,y) coordinates into its raw
- * text, eg (2,3) is "B7" on a 9x9 board.
- *
- * Convention: "translation" is from raw text to program
- * understandable data, "conversion" is the other way around.
- *
- * Globals affected: none
- *
- */
- converttostring(x,y,str)
- COORD x,y ;
- char str[] ;
- {
- COORD temp ;
- char tempstr[3] ;
-
- str[0] = 0 ;
-
- if (x==0 && y==0)
- strcpy(str,"pass") ;
- else
- {
- if (x<=8)
- {
- str[0]= x + 'A' - 1 ;
- }
- else
- {
- str[0] = x + 'J' - 9 ;
- }
-
- str[1] = 0 ;
- temp = size - y + 1 ; /* numbering down */
- sprintf(tempstr,"%d",temp) ;
- strcat(str,tempstr) ;
-
- }
- }
-
- void
- main(argc,argv)
- int argc ;
- char *argv[] ;
- {
- ACTIONTYPE action ;
- char actbuffer[MAXLINELENGTH] ;
- BOOLEAN oktoexit ;
- BOOLEAN legalmove ;
- char text[MAXLINELENGTH] ;
- BOOLEAN skip ;
- int indx ;
-
-
- startterminalspecific(argc,argv) ;
-
-
- currentmove = 1 ;
-
-
- filename[0] = 0 ;
- rawindex = 0 ; /* dont put in zeroboard */
-
- zeroboard() ;
-
- erasescreen() ;
-
- flag[PRACTICE] = off ;
- flag[STEPPING] = off ;
- refreshmenu() ;
-
- /* Get the parameters */
-
- for (indx=1 ; indx<argc ; indx++)
- {
- if (strcmp("-d",argv[indx]) == 0 )
- {
- indx++ ;
- strcpy(directory,argv[indx]) ;
- }
-
- if (strcmp("-r",argv[indx]) == 0 )
- {
- indx++ ;
- readin(argv[indx]) ;
- strcpy (filename,argv[indx]) ;
- }
- else
- {
- initialiseflags() ;
- }
- }
-
-
-
- action = noselection ;
-
- oktoexit=FALSE ;
- while (oktoexit!=TRUE)
- {
- getinput(&action, actbuffer) ;
-
- switch ( (int)action )
- {
-
- case noselection :
- break ;
-
- case stoneplayed :
- if (flag[PRACTICE]==off)
- {
- if (flag[STEPPING]==off)
- {
- legalmove = domove((COORD)actbuffer[0],(COORD)actbuffer[1],realboard) ;
- if (legalmove==TRUE)
- convertandstore((COORD)actbuffer[0],(COORD)actbuffer[1]) ;
- }
- }
- else
- (void)domove((COORD)actbuffer[0],(COORD)actbuffer[1],practiceboard) ;
- break ;
-
- case undo :
-
- if (flag[PRACTICE]==off)
- {
- if (flag[STEPPING]==on)
- steppingindex = undorawindex ;
- else
- {
- if (undorawindex < (rawindex-1))
- {
- displaystring("Comments also removed") ;
- clearpromptline() ;
- }
- rawindex = undorawindex ;
- }
-
- removedifferences(realboard,
- undoboard) ;
- currentmove = savedcurrentmove ;
- komove = savedkomove ;
- blackcaptured = savedblackcaptured ;
- whitecaptured = savedwhitecaptured ;
- displaycaptured() ;
- strcpy( lastmovestring, savedlastmovestring ) ;
- displaylastmove(lastmovestring) ;
- refreshmenu() ;
- }
- else
- {
- /* take flag off temporaily */
- flag[PRACTICE] = off ;
- removedifferences(practiceboard,
- undopracticeboard) ;
- flag[PRACTICE] = on ;
- komove = savedkomove ;
- nextpracticestone = savednextpracticestone ;
- }
- break ;
- case rawkeyboard :
- if ( (flag[PRACTICE]==on) ||
- ((flag[STEPPING]==off) &&
- (flag[PRACTICE]==off)) )
- {
- legalmove = translateline(actbuffer, text, &skip) ;
- if (legalmove==TRUE)
- {
- if (flag[PRACTICE]==off)
- store(actbuffer) ;
- }
- else
- {
- clearpromptline() ;
- displaystring(ILLEGAL) ;
- }
- }
- clearpromptline() ;
- break ;
- case lastmove :
- toggleflag(LASTMOVE) ;
- break ;
- case grid :
- toggleflag(GRID) ;
- break ;
- case numbers :
- toggleflag(NUMBERS) ;
- break ;
- case practice :
- if (flag[PRACTICE]==off)
- {
- nextpracticestone=stonecolour(currentmove);
- copyboard(realboard,practiceboard) ;
- flag[PRACTICE] = on ;
- }
- else
- {
- flag[PRACTICE] = off ;
- removedifferences(practiceboard,
- realboard) ;
- }
- refreshmenu() ;
- break ;
- case stepthrough :
- startstepping() ;
- break ;
- case readfrom :
- if (flag[PRACTICE]==off)
- {
- tempfilename[0]=0 ;
- getfilename(tempfilename) ;
- if (tempfilename[0]!=0)
- {
- flag[STEPPING] = off ;
- refreshmenu() ;
- readin(tempfilename) ;
- strcpy (filename,tempfilename) ;
- }
- }
- break ;
- case pass :
- passmove() ;
- if (flag[PRACTICE]==off)
- convertandstore(0,0) ;
- break ;
- case writeto :
- if ( (flag[PRACTICE]==off) &&
- (flag[STEPPING]==off) )
- writefileaway() ;
- break ;
- case redraw :
- erasescreen() ;
- drawboard() ;
- break ;
- case cd :
- getdirectory(tempdirectory) ;
- if (tempdirectory[0]!=0)
- {
- strcpy(directory,tempdirectory) ;
- }
- break ;
- case gotomove :
- if ( (flag[STEPPING]==on) &&
- (flag[PRACTICE]==off) )
- gotoamove(actbuffer) ;
-
- break ;
- case gotoline :
- if ( (flag[STEPPING]==on) &&
- (flag[PRACTICE]==off) )
- gotoaline(actbuffer) ;
-
- break ;
- case changesize :
- if (flag[STEPPING]==on)
- {
- flag[STEPPING] = off ;
- refreshmenu() ;
- }
- resetgame(actbuffer[0],0) ;
- storenewgame(actbuffer[0],0) ;
- break ;
- case changehandicap :
- if (flag[STEPPING]==on)
- {
- flag[STEPPING] = off ;
- refreshmenu() ;
- }
- resetgame(actbuffer[0],actbuffer[1]) ;
- storenewgame(actbuffer[0],actbuffer[1]);
- break ;
- case spacebar :
- if (flag[PRACTICE]==on)
- {
- nextpracticestone=stonecolour(currentmove);
-
- /* need to turn flag[PRACTICE] off
- * temporarily so that the numbers
- * will be printed in the stones
- * that had been taken off in the
- * practice
- */
- flag[PRACTICE] = off ;
- removedifferences(practiceboard,
- realboard) ;
- flag[PRACTICE] = on ;
-
- copyboard ( realboard,practiceboard) ;
- }
- else
- {
- if (flag[STEPPING]==on)
- readastep() ;
- }
- break ;
- case quit :
- endterminalspecific() ;
- oktoexit = TRUE ;
- break ;
-
- default :
- errorprint("Illegal action returned from getinput()");
- break ;
- } /* switch */
-
- } /* while */
-
- exit(0);
- }
- SHAR_EOF
- fi
- if test -f 'go.curses.c'
- then
- echo shar: "will not over-write existing file 'go.curses.c'"
- else
- cat << \SHAR_EOF > 'go.curses.c'
- #include <curses.h>
- #include <signal.h>
- #include <string.h>
- #include <sys/types.h>
-
- #include "go.h"
- #include "go.extern.h"
-
- /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
- #define RETURN 13
- #define BACKSPACE 0x08
-
- #define CNTRL_C 0x03
- #define CNTRL_D 0x04
- #define CNTRL_G 0x07
- #define CNTRL_H 0x08
- #define CNTRL_L 0x0c
- #define CNTRL_N 0x0e
- #define CNTRL_P 0x10
- #define CNTRL_R 0x12
- #define CNTRL_T 0x14
- #define CNTRL_U 0x15
- #define CNTRL_W 0x17
- #define CNTRL_X 0x18
-
- #define EMPTYPOINT '.'
- #define BLACKSTONE '@'
- #define WHITESTONE 'O'
- #define TICK '*'
- #define NOTICK ' '
-
- #define MENUSIZE 13 /* number of elements in the menu */
-
- #define YLEDGE 1 /* Y coordinate (ie down), low edge of the board */
- #define XLEDGE 3 /* X coordinate (ie across), low edge of the board */
- #define XMENU 55 /* X coord, start of menu */
- #define PROMPTLINE 23 /* Y coord, position where all text appears */
-
- #define MENUSTR " ^H - display Help menu"
- #define ENTERSIZE "Enter size :"
- #define ENTERHANDICAP "Enter handicap :"
- #define ENTERGOTOMOVE "Enter a move or its number (eg D3 or 12) :"
- #define ENTERGOTOLINE "Enter the line number :"
- #define ENTERFILENAME "Enter filename :"
- #define ENTERDIRECTORY "Enter directory :"
- #define CAPTURES "Captures :"
- #define CBLACK "black = "
- #define CWHITE "white = "
- #define LASTSTR "Last : "
-
- /******************************************/
- /* Global variables specific to this file */
- /******************************************/
-
- ONOFF menuflag ;
-
- BOOLEAN menuofflasttime ;
-
- char *menu[MENUSIZE] =
- {
- " ^P - Practice ", /* has to be as long as MENUSTR */
- " ^T - step Through",
- " ^R - Read from",
- " ^U - Undo",
- " ^C - Configure",
- " ^W - Write to",
- " ^L - redraw",
- " ^D - change Directory",
- " ^G - Goto move ( )",
- " ^N - goto liNe ( )",
- " ^X - eXit",
- "",
- " ^H - clear Help menu",
- } ;
-
- int xmiddle ; /* Position to write the 'stones captured' info */
- BOOLEAN killline ; /* Inicates that abort/del has been pressed */
-
- void displayflag() ;
-
-
- /*
- * Function: clearpromptline
- *
- * Description: Clears the player input/comment display line.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- clearpromptline()
- {
- scroll(stdscr) ;
- refresh() ;
- }
-
- /*
- * Function: displaystring()
- *
- * Description: Displays a string in the promptline, if it ends in a
- * newline this is removed before output.
- *
- *
- * Globals affected: none
- *
- */
- void
- displaystring(s)
- char *s ;
- {
- char len ;
-
- len = strlen(s) ;
-
- if ( *(s+len-1) == '\n' )
- {
- *(s+len-1) = '\0' ;
- mvaddstr(PROMPTLINE,0,s) ;
- *(s+len-1) = '\n' ;
- }
- else
- {
- mvaddstr(PROMPTLINE,0,s) ;
- }
- refresh() ;
- }
-
- /*
- * Function: errorprint()
- *
- * Description: Prints a string in error format
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- errorprint(s)
- char *s ;
- {
- standout() ;
- displaystring(s) ;
- standend() ;
- clearpromptline() ;
- displaystring(" ... hit any key to continue") ;
- clearpromptline() ;
- displaystring("(if the program crashes type '^Jstty sane^J')" ) ;
- getch() ;
- }
-
- /*
- * Function: displaylastmove
- *
- * Description: Checks the state of teh last move falg then if required
- * displays the last move.
- *
- *
- * Globals affected: none
- *
- */
- void
- displaylastmove(str)
- char str[] ;
- {
- char i ;
-
- if (flag[LASTMOVE]==on)
- {
- mvaddstr(YLEDGE+4,xmiddle,LASTSTR) ;
- mvaddstr(YLEDGE+4,xmiddle+strlen(LASTSTR),str) ;
- for (i=strlen(str);i<4;i++)
- {
- mvaddch(YLEDGE+4,xmiddle+strlen(LASTSTR)+i,' ') ;
- }
- }
- }
-
- /*
- * Function: erasescreen()
- *
- * Description: Clear the whole screen
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- erasescreen()
- {
- clear() ;
- refresh() ;
-
- menuofflasttime = FALSE ;
- displaymenu() ;
- refresh() ;
-
- }
-
- /*
- * Function: reconfigure()
- *
- * Description: Terminal specific code after a configure of the board
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- reconfigure()
- {
- if (size>MENUSIZE)
- setscrreg(size+2,23) ;
- else
- setscrreg(MENUSIZE+2,23) ;
-
- /* put the captured score between the board and the menu */
- xmiddle = ( ( (size-1)*2+XLEDGE ) + XMENU ) / 2 - ( strlen(CAPTURES)/2 ) ;
-
- }
-
- /*
- * Function: getinput()
- *
- * Description: Gets input from keyboard.
- * Sets action to be one of the following, with corresponding
- * data in the buffer.
- * Any strings returned in the buffer always end with a newline
- * and a null.
- *
- * action actbuffer
- * ------ ---------
- * cd null
- * gotomove decimal string "1" to "999" or a move eg "D3",
- * ending with newline. Maximum of four bytes long,
- * plus '\0'.
- * gotoline decimal string "1" to "999" ending with newline.
- * Maximum of four bytes long, plus '\0'.
- * changehandicap first byte is size, second is handicap
- * numbers null (NOT AVAILABLE WITH CURSES)
- * pass null (NOT AVAILABLE WITH CURSES)
- * practice null
- * quit null
- * rawkeyboard string typed in from the keyboard + "\n"
- * readfrom null
- * redraw null
- * changesize first byte indicates new size
- * (NOT AVAILABLE WITH CURSES)
- * spacebar null
- * stoneplayed x and y in the first two bytes
- * (NOT AVAILABLE WITH CURSES)
- * stepthrough null
- * undo null
- * writeto null
- *
- * This function handles the displaying of the menu (together
- * with the associated flags). The current move must be
- * displayed on the menu in a relevant place.
- *
- * Globals affected: none
- *
- */
- void
- getinput ( action, actbuffer )
- ACTIONTYPE *action ;
- char actbuffer[MAXLINELENGTH] ;
- {
-
- chtype key ;
- char sizestr[4] ;
- char handstr[3] ;
-
- /* move the cursor to the menu to indicate ready for input */
- if (menuflag==on)
- move(YLEDGE+MENUSIZE-1,XMENU+strlen(menu[MENUSIZE-1])) ;
- else
- move(YLEDGE,XMENU+strlen(MENUSTR)) ;
-
- refresh() ;
-
- key = getch() ;
-
- switch(key)
- {
- case CNTRL_C :
- mvaddstr(PROMPTLINE,0,ENTERSIZE) ;
- refresh() ;
- collectstring(strlen(ENTERSIZE),
- sizestr,
- 0,2 ) ;
- clearpromptline() ;
- actbuffer[0] = atoi(sizestr) ;
-
- mvaddstr(PROMPTLINE,0,ENTERHANDICAP) ;
- refresh() ;
- collectstring(strlen(ENTERHANDICAP),
- handstr,
- 0,1 ) ;
- clearpromptline() ;
- actbuffer[1] = atoi(handstr) ;
-
- *action = changehandicap ;
- break;
- case CNTRL_D :
- *action = cd ;
- break;
- case CNTRL_G :
- clearpromptline() ;
- mvaddstr(PROMPTLINE,0,ENTERGOTOMOVE) ;
- refresh() ;
- collectstring(strlen(ENTERGOTOMOVE),
- actbuffer,
- 0,3 ) ;
- strcat(actbuffer,"\n") ;
- clearpromptline() ;
- *action = gotomove ;
- break;
- case CNTRL_L :
- *action = redraw ;
- break;
-
- case CNTRL_N :
- clearpromptline() ;
- mvaddstr(PROMPTLINE,0,ENTERGOTOLINE) ;
- refresh() ;
- collectstring(strlen(ENTERGOTOLINE),
- actbuffer,
- 0,3 ) ;
- strcat(actbuffer,"\n") ;
- clearpromptline() ;
- *action = gotoline ;
- break;
-
- case CNTRL_H : if (menuflag==on)
- menuflag=off ;
- else
- menuflag=on ;
-
- displaymenu() ;
- *action = noselection ;
- break ;
-
- case CNTRL_P :
- clearpromptline() ;
- *action = practice ;
- break;
- case CNTRL_R :
- *action = readfrom ;
- break;
- case CNTRL_T :
- *action = stepthrough ;
- break;
- case CNTRL_U :
- *action = undo ;
- break ;
- case CNTRL_W :
- *action = writeto ;
- break;
-
- case CNTRL_X : *action = quit ;
- break ;
-
-
- case ' ' : *action = spacebar ;
- break ;
-
- default : mvaddch(PROMPTLINE,0,(char)key) ;
- refresh() ;
- actbuffer[0]=(char)key ;
- collectstring(0,actbuffer,1,MAXCHARS) ;
- strcat(actbuffer,"\n") ;
- *action= rawkeyboard ;
- break ;
- }
- }
-
- /*
- * Function: drawgrid
- *
- * Description: Draws the 'A' to 'T' along the top and 19 to 1 down the side
- * Providing that the grid flag is set.
- *
- *
- * Globals affected: none
- *
- */
- void
- drawgrid()
- {
- char str[3] ;
- int indx ;
-
- if (flag[GRID]==on)
- {
- for (indx=1;indx<=size;indx++)
- {
- if (indx<=8)
- {
- mvaddch(0,(indx-1)*2+XLEDGE,'A'+indx-1) ;
- }
- else
- {
- mvaddch(0,(indx-1)*2+XLEDGE,'J'+indx-9) ;
- }
-
- str[0] = 0 ;
- sprintf(str,"%d",size+1-indx) ;
- mvaddstr(YLEDGE+indx-1,0,str) ;
-
- refresh() ;
- }
- }
- }
-
- /*
- * Function: drawempty
- *
- * Description: Draws an empty place on the board
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- drawempty(x,y)
- COORD x,y ;
- {
- mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, EMPTYPOINT ) ;
- refresh() ;
- }
-
- /*
- * Function: drawstone
- *
- * Description: Draws a stone, with number if possible/allowed
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- drawstone(x,y,n,c)
- COORD x,y ;
- MOVENUMBER n ;
- COLOUR c ;
- {
- if (flag[PRACTICE]==on)
- attron(A_BOLD) ;
- /*standout() ; - reverse video */
-
- if (c==black)
- mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, BLACKSTONE ) ;
- else
- mvaddch( YLEDGE+y-1, (x-1)*2+XLEDGE, WHITESTONE ) ;
-
- if (flag[PRACTICE]==on)
- attroff(A_BOLD) ;
- /*standend() ; - reverse video */
-
- refresh() ;
-
- displaymenu() ;
- }
-
- /*
- * Function: getdirectory
- *
- * Description: If directory is already set then copy directory into dn.
- * Display dn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected: none
- *
- */
- void
- getdirectory(dn)
- char dn[] ;
- {
- clearpromptline() ;
-
- mvaddstr(PROMPTLINE,0,ENTERDIRECTORY) ;
-
- dn[0]=0 ;
- strcpy(dn,directory) ;
- mvaddstr(PROMPTLINE,strlen(ENTERDIRECTORY),dn) ;
-
- refresh() ;
-
- collectstring(strlen(ENTERDIRECTORY),
- dn,
- strlen(dn),
- MAXCHARS ) ;
-
- clearpromptline() ;
- }
-
- /*
- * Function: getfilename
- *
- * Description: If filename is already set then copy filename into fn.
- * Display fn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected: none
- *
- */
- void
- getfilename(fn)
- char fn[] ;
- {
- clearpromptline() ;
-
- mvaddstr(PROMPTLINE,0,ENTERFILENAME) ;
-
- fn[0]=0 ;
- strcpy(fn,filename) ;
- mvaddstr(PROMPTLINE,strlen(ENTERFILENAME),fn) ;
-
- refresh() ;
-
- collectstring(strlen(ENTERFILENAME),
- fn,
- strlen(fn),
- MAXLINELENGTH ) ;
-
- clearpromptline() ;
- }
-
- /*
- * Function: displaycaptured
- *
- * Description: Displays on the screen how many of each colour have been taken.
- *
- * Globals affected: none
- *
- */
- void
- displaycaptured()
- {
- char taken[4] ;
-
- mvaddstr(YLEDGE,xmiddle,CAPTURES) ;
- mvaddstr(YLEDGE+1,xmiddle,CBLACK) ;
- mvaddstr(YLEDGE+2,xmiddle,CWHITE) ;
-
- taken[0] = 0 ;
- sprintf(taken,"%d",blackcaptured) ;
- mvaddstr(YLEDGE+1,xmiddle+strlen(CBLACK),taken) ;
-
- taken[0] = 0 ;
- sprintf(taken,"%d",whitecaptured) ;
- mvaddstr(YLEDGE+2,xmiddle+strlen(CWHITE),taken) ;
- }
-
- /*
- * Function: refreshmenu()
- *
- * Description: This function is called when some information on the menu
- * has changed, the screen needs updating.
- *
- *
- * Globals affected: none
- *
- */
- void
- refreshmenu()
- {
- displayflag(STEPPING) ;
- displayflag(PRACTICE) ;
-
- /* other flags are ignored in curses version */
-
- displaymenu() ;
- }
-
- /*
- * Function: startterminalspecific
- *
- * Description: Graphics routines initialisation etc.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- startterminalspecific(argc,argv)
- int argc ;
- char *argv[] ;
- {
- int handler() ;
-
- signal(SIGINT, handler) ; /* handle abort (del) */
-
- initscr() ;
- nonl() ;
- cbreak() ;
- noecho() ;
- scrollok(stdscr,1) ;
-
-
- menuflag = off ;
-
- menuofflasttime = FALSE ;
-
- displaystring(version) ;
- setscrreg(21,23) ;
-
- }
-
- /*
- * Function: endterminalspecific
- *
- * Description: Graphics routines termination before exit.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- endterminalspecific()
- {
- clearpromptline() ;
- endwin() ;
- }
-
- /******************************/
- /* End of Interface functions */
- /******************************/
-
-
- /*
- * Function: displayflag
- *
- * Description: Displays on the menu the status of the specified flag.
- *
- * Globals affected: none
- *
- */
- void
- displayflag(f)
- char f ;
- {
- char action ;
-
- if (flag[f]==off)
- action = NOTICK ;
- else
- action = TICK ;
-
- switch(f)
- {
- case STEPPING : menu[1][0] = action ;
- break ;
- case PRACTICE : menu[0][0] = action ;
- break ;
- case NUMBERS :
- case GRID :
- case LASTMOVE :
- /* ignore, these are not displayed in curses */
- break ;
-
- default : errorprint("default case in displayflag()") ;
- break ;
-
- }
-
- }
- /*
- * Function: removemenuitem()
- *
- * Description: Clears item n of the menu off the screen
- *
- *
- *
- * Globals affected: none
- *
- */
- removemenuitem(n)
- int n ;
- {
- int count ;
-
- for ( count=0 ; count<strlen(menu[n]) ; count++ )
- {
- mvaddch(YLEDGE+n,XMENU+count,' ') ;
- }
- refresh() ;
- }
-
- /*
- * Function: displaymenu()
- *
- * Description: Displays the menu according to the menuflag
- *
- *
- * Globals affected: menuofflasttime
- *
- */
- displaymenu()
- {
- int indx ;
- char gotostr[4] ;
-
- if (menuflag==off)
- {
- if (menuofflasttime == FALSE)
- {
- for (indx=(MENUSIZE-1);indx>=0;indx--)
- {
- removemenuitem(indx) ;
- }
- mvaddstr(YLEDGE,XMENU,MENUSTR) ;
- menuofflasttime = TRUE ;
- refresh() ;
- }
- }
- else
- {
- for (indx=0;indx<MENUSIZE;indx++)
- {
- mvaddstr(YLEDGE+indx,XMENU,menu[indx]) ;
- }
- menuofflasttime = FALSE ;
-
- gotostr[0] = 0 ;
- sprintf(gotostr,"%d",currentmove-1) ;
- mvaddstr(YLEDGE+8,XMENU+18,gotostr) ;
-
- gotostr[0] = 0 ;
- sprintf(gotostr,"%d",steppingindex) ;
- mvaddstr(YLEDGE+9,XMENU+18,gotostr) ;
-
- refresh() ;
- }
-
-
-
- }
-
- /*
- * Function: collectstring()
- *
- * Description: Allows player to enter a sting of chars on the promptline,
- * if strsize is non-zero this implies some characters are
- * already persent. The string can be editted using backspace
- * or terminal interrupt key (removes the whole line).
- *
- *
- * Globals affected: none
- *
- */
- collectstring(xstart,str,strsize,max)
- int xstart ; /* position on PROMPTLINE where initial string started */
- char *str ; /* string to be filled */
- int strsize ; /* count of chars already in str */
- int max ; /* maximum numbers characters that can be input */
- {
-
- #define NO_CHAR (chtype)(-1) /* no key pressed yet */
-
- chtype key ;
- int indx ;
-
- key = NO_CHAR ;
-
- nodelay(stdscr,1) ;
-
- killline = FALSE ; /* see handler() */
-
- while ( key!=RETURN )
- {
- key = getch() ;
-
- if (killline==TRUE)
- {
- if (strsize>0)
- {
- for (indx=xstart+strsize-1;
- indx>=xstart;
- indx--)
- mvaddch(PROMPTLINE,indx,' ');
- strsize = 0 ;
- move(PROMPTLINE,xstart) ;
- refresh() ;
- }
- killline = FALSE ;
- }
-
- if (key!=NO_CHAR)
- {
- switch(key)
- {
- case RETURN : *(str+strsize) = 0 ;
- break ;
-
- case BACKSPACE :if (strsize>0)
- {
- strsize-- ;
- mvaddch(PROMPTLINE,
- xstart+strsize,
- ' ') ;
- move(PROMPTLINE,xstart+strsize);
- refresh() ;
- }
- break ;
-
- default : if (strsize<max)
- {
- *(str+strsize) = (char)key ;
- mvaddch(PROMPTLINE,xstart+strsize,(char)key) ;
- refresh() ;
- strsize++ ;
- }
- break ;
- } /* end switch */
-
- } /* end if ! NO_CHAR */
-
- } /* end while */
-
- nodelay(stdscr,0) ;
- }
-
- /*
- * Function: handler
- *
- * Description: Deals with interrupts sent to this process, the only one
- * we are interested in is 'terminal interrupt'
- *
- *
- * Globals affected: killline
- *
- */
- handler(a)
- int a ;
- {
- /* reset the signal so it can be caught again */
- signal(SIGINT, handler) ; /* handle abort (del) */
-
- switch (a)
- {
- case SIGINT : killline = TRUE ;
- break ;
-
- default : beep() ;
- break ;
- }
- return(0) ;
- }
-
- SHAR_EOF
- fi
- if test -f 'go.extern.h'
- then
- echo shar: "will not over-write existing file 'go.extern.h'"
- else
- cat << \SHAR_EOF > 'go.extern.h'
- /*
- * This is used as an include file for the terminal interface driver routines,
- * it contains all the external global varibales defined in go.c and any
- * functions found in go.c that could be useful to the driver.
- */
-
- extern char version[] ;
- extern COLOUR black ;
- extern COLOUR white ;
-
- extern char size ;
- extern char handicap ;
-
- extern MOVENUMBER currentmove ;
- extern int steppingindex ;
-
- extern char filename[FILENAMELEN] ;
- extern char directory[MAXLINELENGTH] ;
-
- extern ONOFF flag[5] ;
-
- extern int blackcaptured ;
- extern int whitecaptured ;
-
-
- BOOLEAN starpoint() ;
- POSTYPE postype() ;
- SHAR_EOF
- fi
- if test -f 'go.h'
- then
- echo shar: "will not over-write existing file 'go.h'"
- else
- cat << \SHAR_EOF > 'go.h'
- /*
- * #defines and types useful to both go.c and go.<driver>.c
- */
-
- #define EMPTY 0
-
- /* max board array size [0] is always empty */
- #define MAX 20
-
- #define MOVENUMBER unsigned short /* 1 to 999 */
- #define COORD unsigned short /* 1 to 19 */
- #define COLOUR unsigned short /* If handicap is zero then 1 = black and
- * 2 = white, else 1 = white and 2 = black
- */
-
- /* flag definitions */
- #define STEPPING 0
- #define PRACTICE 1
- #define NUMBERS 2
- #define GRID 3
- #define LASTMOVE 4
-
- /* largest line length in the file */
- #define MAXLINELENGTH 82
- #define MAXCHARS (MAXLINELENGTH-2) /* allow room for "\n\0" */
-
- /* longest filename length */
- #define FILENAMELEN 14
-
- typedef enum POSTYPE
- {
- topleft,
- topside,
- topright,
- leftside,
- middle,
- rightside,
- bottomleft,
- bottomside,
- bottomright
- } POSTYPE ;
-
-
-
-
- typedef enum ACTIONTYPE
- {
- noselection,
- quit,
- stoneplayed,
- rawkeyboard,
- lastmove,
- numbers,
- grid,
- practice,
- stepthrough,
- changesize,
- readfrom,
- pass,
- undo,
- writeto,
- redraw,
- cd,
- gotomove,
- gotoline,
- changehandicap,
- spacebar
- } ACTIONTYPE ;
-
-
- typedef enum ONOFF { on,off } ONOFF ;
-
-
- #ifndef TRUE /* curses.h already declares its own TRUE and FALSE */
-
- typedef enum BOOLEAN
- {
- FALSE = 0,
- TRUE = 1
- } BOOLEAN ;
-
- #else
-
- #define BOOLEAN unsigned char
-
- #endif
-
- typedef struct XY
- {
- unsigned char x ;
- unsigned char y ;
- } XY ;
-
-
- SHAR_EOF
- fi
- if test -f 'go.interface.h'
- then
- echo shar: "will not over-write existing file 'go.interface.h'"
- else
- cat << \SHAR_EOF > 'go.interface.h'
- /*
- * Definitions of all the functions that need to be supplied by the terminal
- * interface driver
- */
- extern void clearpromptline() ;
- extern void displaycaptured() ;
- extern void displaylastmove() ;
- extern void displaystring() ;
- extern void drawempty() ;
- extern void drawgrid() ;
- extern void drawstone() ;
- extern void endterminalspecific() ;
- extern void erasescreen() ;
- extern void errorprint() ;
- extern void getdirectory() ;
- extern void getfilename() ;
- extern void getinput() ;
- extern void reconfigure() ;
- extern void refreshmenu() ;
- extern void startterminalspecific() ;
- SHAR_EOF
- fi
- if test -f 'go.mmx'
- then
- echo shar: "will not over-write existing file 'go.mmx'"
- else
- cat << \SHAR_EOF > 'go.mmx'
- .DS C
-
-
-
-
-
-
- .B
- GO MANUAL
-
- .I
- User Guide and Programmer Reference
- .R
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .DE
- .DS CB
- GO - is a game that originated in China over
- 4000 years ago and is now the national game
- of Japan. It's rules are simple but the game
- can take a life time to master. An advantage
- of the game is that there is a handicapping
- system whereby less experienced players still
- give stronger players a good match.
- .DE
- .SK
- .H 1 "INTRODUCTION"
- .P
- This document describes a program that provides a screen based board for the
- playing of the game Go. It is written in C for the Unix operating system and
- the code is split in such a way as to enable the program to run on any type of
- terminal, providing the terminal interface driver has been written. At the
- moment there are drivers for standard terminals that can cope with the Unix
- "curses" package and for the 630 DMD terminal. This document makes references
- to both these interfaces.
- .P
- Section 2 gives a brief walk through of how to get going using the program.
- Section 3 gives a beginners tutorial on the rules of Go, section 4 describes
- all the features of the program and how to use them.
- .H 1 "GETTING STARTED"
- .H 2 "Sample .profile"
- .P
- Initially a player should edit their .profile to include the following lines :-
- .DS
- .
- .
- GO=/d1/usr/go #or where-ever the root is
- export GO
- PATH=$PATH:$GO/bin
- alias go="go -d $GO/games" #Set default directory
- .
- .
- .DE
- .P
- The $GO environment variable should point to the root of the go directory tree.
- $GO/games contains some sample games as well as the 'tutoring' games mentioned
- in the sections below. Later the alias to set the default directory could point
- to the player's personal games directory. (see section:INVOCATION)
- .H 2 "For Standard Terminals"
- .P
- Typing "go" at the Unix prompt the screen will be cleared, to display the menu
- of options type cntrl-H ( a further cntrl-H will remove the menu, it is not
- necessary to display the menu to access the commands, it is just a "reminder" ).
- Type cntrl-T ( for "step Through" ) and you will be prompted for a filename,
- enter 'start.go' and press return the program will then be reading in this file.
- Start.go is a file that will guide you through the basics of using the program.
- .H 2 "For 630 Terminals"
- .P
- Draw a fairly large window and type "go" at the Unix prompt, the window
- will then begin to fill. After the screen has filled, the window will change
- shape to become square and
- program is ready. Button 3 of the mouse presents you with a menu of options,
- select "step through" and enter the filename start.630.go which will guide you
- through using the basics of the program. Note that as well as being able to
- enter moves as described you can also play them with button 1 of the mouse.
- Button 2 can also be used as a substitute for the space bar.
- .P
- Moves will have the number displayed on the stone if the number flag is set,
- see below. Numbers are not displayed on practice stones or handicap stones.
- .P
- Two people can play face to face using the 630 version of the program : one
- player takes the mouse, the other the keyboard.
- .H 1 "GO FOR BEGINNERS"
- .P
- Once you have mastered using the program, section 2 above, step through a
- file called 'basics.go' which explains the rules of the game.
- .H 2 "Handicapping and Ranking System"
- Players of Go are rated using a 'kyu' (pronounced "Q") ranking system,
- beginners generally start at around 25 kyu, more accomplished players
- have a lower kyu rating. The difference in kyu between two players is the
- number of handicap stones that are to be placed on the board in set positions
- before the game starts.
- .P
- For example if a 17 kyu plays against a 21 kyu then the less experienced
- player (the 21 kyu) has four of his/her stones placed at the 4,4 points in
- each corner of a 19x19 board (such handicap points are sometimes called "star
- points"). Notice that the less experienced player
- always plays black and that after the handicap stones are placed then it is
- white's first move.
- .P
- After a player improves beyond 1 kyu then he/she progresses up in 'dan' grades
- ie the sequence goes ... 2 kyu, 1 kyu, 1 dan (or sho-dan), 2 dan, 3 dan, etc up
- to 9 dan.
- The best players in Europe are around 4-5 dan and in Japan a 6 dan or higher
- could earn a living as a professional go player !
- .H 1 "THE DETAILS"
- .H 2 "Modes of Use"
- .P
- There a two basic ways to use the program:-
- .H 3 "Learning/Researching"
- Step through a file, using the space bar. Allow the player to select practice
- and try some moves out, while practicing the spacebar removes the practice
- stones, select "practice" again to continue to step. Writing of files away is
- prevented when stepping. Should the player wish to quit and return at a later
- date back to the place where he/she left off, then before quitting look at the
- menu for "goto line" it will indicate the current line in the file.
- .P
- It is also possible to goto any move within a game by specifying it's move
- number (or with grid coordinates for the 'curses' version of the program).
- Note that there can be more than one game per file.
- .H 3 "Playing/Existing Games"
- Enter moves using mouse or keyboard, comments can also be typed in. Write the
- file away, if the file had previously been read in then only the new moves and
- comments are appended to the file providing the same filename is entered.
- Possible to make practice moves by selecting "practice" on the menu, spacebar
- will remove the practice stones, to make a 'real' move, the player needs to
- select "practice" again.
- .H 2 "File Format"
- Each line of the files read in and written away conform to one of the following
- patterns. Note this is also the format for typing commands at the keyboard.
- Each block shown in the diagrams can optionally be separated by white spaces (
- ie spaces or tabs).
- .P
- The pipe
- character '|' is used when stepping through a file, if it is present at the end
- of a line then there is no pause waiting for the player to press space bar, the
- program continues on to read the next line.
- .H 3 "Configure"
- .DS CB
- .GS
- @---@
- @--------@ @-------------@ @--------@ | |
- ----| number |--| white space |-|-| number |-|-|--| | |--------|----
- @--------@ | or carriage | | @--------@ | | | | |
- | return | | | | @---@ |
- @-------------@ |------------| | |
- | @---------@ |
- |--| Comment |--|
- | @---------@ |
- | |
- |---------------|
- .GE
- .DE
- .P
- The first number is the size of the board, the second is the handicap. If
- the second number is omited then then the handicap is assumed to be zero.
- .H 3 "A Move"
- .DS CB
- .GS
- @---@
- @--------@ @--------@ | |
- ----|--| letter |--| number |--|--|--| | |--------|----
- | @--------@ @--------@ | | | | |
- | | | @---@ |
- | | | |
- | @--------@ | | @---------@ |
- |--| "pass" |--------------| |--| Comment |--|
- @--------@ | @---------@ |
- | |
- |---------------|
- .GE
- .DE
- One ascii letter 'a' to 't', no 'i' followed by a number represents the
- coordinatesof a move. The string "pass" is used when a player decides there
- are no moves he or she could sensibly make (when both players pass the game
- is over)
- .H 3 "Comment"
- .DS CB
- .GS
- @---@
- @---@ @--------------@ | |
- ------| # |---| ascii string |--|--| | |--|---
- @---@ @--------------@ | | | |
- | @---@ |
- |---------|
- .GE
- .DE
- .H 3 "Control"
- .DS CB
- .GS
- @---@ @--------------@ @---------@
- ----| ! |-----| control word |-----|----| Comment |----|----
- @---@ @--------------@ | @---------@ |
- | |
- |-------------------|
- .GE
- .DE
- .P
- Possible values of the control word are:-
- .VL 12 2
- .LI "grid"
- Toggles the displaying of the grid (coordinates around the board).
- .LI "numbers"
- Toggles the displaying of the numbers on the stones (only meaningful for 630s).
- .LI "lastmove"
- Toggles the displaying of the Last Move.
- .LI "clear"
- Erases the screen.
- .LE
- .H 2 "Features Explained"
- This section explains the features available to the players.
- .BL
- .LI
- \fIChange Directory\fR - The default directory can be passed as a parameter
- to the program. Using the 'change directory' command the player can change
- this string.
- The directory string will be prepended to any filename entered.
- .LI
- \fIConfigure\fR - Configuring erases any current game in progress. The player
- is prompted for the size and handicap of the new game. Handicaps are only
- available on board sizes 9, 13 and 19 and handicaps higher than 5 are only
- allowed on a size 19 board. CONFIGURING OVERWRITES THE PREVIOUS GAME IF NOT
- STEPPING.
- .P
- Configuring may be accomplished via the keyboard or menu.
- .LI
- \fIControls\fR - Controls are ways the player can configure the internal
- parameters of the program. In general they can be toggled on or off via
- keyboard input, or in the case of 630 terminals via the menu.
- .DL
- .LI
- \fIGrid\fR The grid is the axis coordinates displayed around the board.
- .LI
- \fINumbers\fR Display the numbers on the stones (630 terminals only)
- .LI
- \fILast Move\fR The last move is by default displayed, this control allows
- it to be not displayed.
- .LI
- \fIClear\fR Erase the screen.
- .LE
- .LI
- \fIGoto\fR - Goto is only a valid option if the stepping flag is on and practice
- flag is off.
- There are two types of goto :-
- .DL
- .LI
- \fIGoto Move\fR Displayed on the menu is the current move number within a game
- , it is possible to goto any move within a game either by specifying the move
- number or by it's grid coordinates if player is using the 'curses' version of
- the program.
- .LI
- \fIGoto Line\fR Also displayed on the menu is the current line number within
- the file the player is stepping through. It is possible to goto to any line
- within the file.
- .LE
- .LI
- \fIPass\fR - A player can 'pass' via the keyboard (or 630 menu).
- .LI
- \fIPractice\fR - This toggles the practice flag which is displayed on the menu.
- Practicing enables the player
- to try out combinations of moves before deciding on the actual play. Spacebar
- clears the practice stones but play can only continue with the practice flag
- off. During practice stones captured and 'lastmove' are not displayed.
- .LI
- \fIRead From\fR - After entering the filename the moves are displayed on the
- screen while the whole file is read into memory. Further moves by the player(s)
- are appended to this game.
- .LI
- \fIRedraw\fR - Clears the screen and redraws the board.
- .LI
- \fIStep Through\fR - When this is selected the player is prompted for a filename
- to step through. To step through the file press the spacebar (or button 2 of the
- mouse). The stepping flag is indicated on the menu.
- .P
- While stepping moves are not allowed to be entered unless the practice flag is
- on.
- To leave the stepping mode select "read from" or "configure".
- .LI
- \fIUndo\fR - It is possible to undo the last move made (even during practice
- and stepping). Note that if comments were added after a move played the the undo
- will also remove these.
- .LI
- \fIWrite To\fR - Writing files away is only possible if the stepping
- flag is off.
- If "write to" is selected after a file has been read in then the moves played
- after the reading are appended to that existing file (if the filename for
- writing is the same as the one entered for reading). In the other cases the whole
- of the current game is written away.
- .LE
- .H 1 "PROGRAMMER REFERENCE"
- .P
- This section is for programmers who wish to write a terminal interface driver
- for the program.
- .H 2 "Building"
- Here is a list of existing C files.
- .VL 15
- .LI "go.c"
- This contains the 'core' functions of the program including main(). Also
- declares the global variables needed in the terminal interface driver.
- .LI "go.h"
- Header file that defines types common to go.c and go.*.c
- .LI "go.patch.h"
- This header takes care of differences between 630 and 'curses' compilers.
- .LI "go.interface.h"
- Header file that declares the functions defined in the driver file.
- .LI "go.extern.h"
- Header file that contains the variables definitions declared in go.c. This is
- included in go.*.c
- .LI "go.curses.c"
- Terminal interface driver for standard terminals.
- .LI "go.630.c"
- Terminal interface driver for 630 DMD terminals.
- .LI "go.skeleton.c"
- Skeleton of a terminal interface driver.
- .LE
- .P
- To build for a standard terminal:-
- .DS C
- cc -o $GO/bin/go.out go.c go.curses.c -lcurses
- .DE
- .P
- To build for a 630 terminal:-
- .DS C
- dmdcc -o $GO/bin/go.630.out go.c go.630.c
- .DE
- .P
- Note that there is a shell script called 'c' that will perform the above
- commands dependent on $TERM.
- .P
- To build for a new type of terminal make a copy of go.skeleton.c
- (renaming the middle
- portion to something that will indicate the terminal type) and edit it according
- to the interface described in the section below. Also edit the 'go' shell script
- to accommodate the new terminal type.
- .H 2 "Terminal Interface"
- .P
- The following is a description of the functions that must be provided in the
- terminal interface driver.
- .DS
- .B
- void clearpromptline()
- .R
- .DE
- .P
- The promptline is the line that all player entry and comments are displayed on,
- in the "curses" interface driver this function just scrolls the line up and in
- the 630 version sets the text to be written one line lower that the last.
- .DS
- .B
- void displaycaptured()
- .R
- .DE
- .P
- Shows the number of black and white stones captured.
- .DS
- .B
- void displaylastmove(s)
- char *s ;
- .R
- .DE
- .P
- Displays string s in the required format for last move (providing that the
- lastmove flag is ON)
- .DS
- .B
- void displaystring(s)
- char *s ;
- .R
- .DE
- .P
- Displays string s at the prompt line.
- .DS
- .B
- void drawempty(x,y)
- COORD x,y ;
- .R
- .DE
- .P
- Draws an empty place on the board. If using bitmapped displays (eg 630) then
- use postype() and starpoint() (defined in go.c) to determine if it is
- necessasry to draw a small disc to indicate a star point.
- .DS
- .B
- void drawgrid()
- .R
- .DE
- .P
- Draws the coordinate references 'A' to 'T' along the top and 19 to 1 down the
- left side.
- .DS
- .B
- void drawstone(x,y,n,c)
- COORD x,y ;
- MOVENUMBER n ;
- COLOUR c ;
- .R
- .DE
- .P
- Draws a stone of the right colour at (x,y). If the terminal is a bitmapped display
- draw any associated board lines and if the practice flag/number flag allow
- print the number on the stone ( providing that (x,y) is not a star point, move
- number is 2 and the handicap is non zero ). If practice flag is on and this is
- a standard terminal then highlight the stone with bold (bit mapped displays in
- this case do not print a number on the stone).
- .DS
- .B
- void endterminalspecific()
- .R
- .DE
- .P
- Allows the interface driver to perform any terminating graphics routines just
- before exiting the program.
- .DS
- .B
- void erasescreen()
- .R
- .DE
- .P
- Clears the whole screen.
- .DS
- .B
- void errorprint(s)
- char *s ;
- .R
- .DE
- .P
- Displays string as an error to the player. This used to warn of an internal
- error eg default hit in a switch, file unreadable or an error in the
- file being read in.
- .DS
- .B
- void getdirectory(s)
- char *s ;
- .R
- .DE
- .P
- Display "Enter directory :", then if global variable "directory" is not null
- then display it. Allow the player to enter/edit the text using backspace
- and delete (terminal interrupt) keys. The resultant string is copied into *s.
- .DS
- .B
- void getfilename()
- .R
- .DE
- .P
- Display "Enter filename :", then if global variable "filename" is not null
- then display it. Allow the player to enter/edit a suitable string.
- .DS
- .B
- void getinput(action,actionbuffer)
- ACTIONTYPE action ;
- char actionbuffer[MAXLINELENGTH] ;
- .R
- .DE
- .P
- Sets action and actionbuffer (if necessary) according to mouse/keyboard input.
- .DS
- .B
- void reconfigure()
- .R
- .DE
- .P
- Lets the terminal interface driver know that the size/handicap has changed.
- .DS
- .B
- void refreshmenu()
- .R
- .DE
- .P
- The menu displays all the flags, current move and current line. This function
- updates the menu with these values and if necessary displays them on the screen.
- .DS
- .B
- void startterminalspecific()
- .R
- .DE
- .P
- Terminal driver's opportunity to initialise data/screens etc. at the start of
- running the program.
- .H 1 "COMMAND LINE INVOCATION"
- At the unix prompt the 'go' shell script can accept certain parameters :-
- .DS CB
- go [-c] [-d <directory>] [-r <filename>]
- .DE
- .VL 10 5
- .LI "-c"
- \fIFor 630 terminals only\fR Use this option to cache the program so that
- the game can be run after quitting without loading it up again. To remove it
- from cache use the 630 tool 'ucache' which, using button 3, enables the player
- to remove programs from the cache. Note that once a program is cached its
- parameters cannot be changed at a later invocation.
- .LI "-d"
- The parameter after the -d is treated as the default directory which will
- be prepended to any filename within the program.
- .P
- .DS I F 5
- \fIIt is recommended that players set up an alias to use the -d facility so
- that it will point to a directory where all the players' games are stored eg
- alias go="go -d /d1/usr/go"
- \fR
- .DE
- .LI "-r"
- The parameter after the -r is treated as a filename to be read in (not stepped
- through) at the start of the program.
- .LE
- .H 1 "OTHER FILES"
- .P
- The full list of files on release are as follows:-
- .DS
- .TS
- box;
- c|c
- l|l.
- Description
- =
- basics.go Intro. to the rules of go
- bgj.75.go Sample game from the British Go Journal Issue 75
- c Shell script to aid compilation
- example.go A complete introductory game with comments.
- game1.go Sample game played between R.Parker(13) and D.Bradley(2)
- game2.go
- game3.go
- go Shell script to run the program
- go.630.c Terminal interface driver for a 630 terminal
- go.630.out Executable for a 630
- go.c Core functions of the program
- go.curses.c Terminal interface driver for a standard terminal
- go.curses.out Executable for standard terminal.
- go.extern.h Definitions of external variables.
- go.h General header file
- go.mmx This doc.
- go.skeleton.c Skeleton for a terminal interface driver
- go_icon Icon used by 630 terminal
- go.interface.h Terminal interface driver function definitions
- kobattle.go Description of a ko battle
- makefile Used in compilation for standard terminals
- null_icon Icon used by 630 terminal
- go.patch.h Terminal specific patches
- start.630.go How to use the 630 version of the program.
- start.go How to use the standard version of program
- tick_icon Icon used by 630 terminal
- .TE
- .DE
- .H 1 "FURTHER INFO"
- For more information about go playing in the UK please contact the membership
- secretary of the British Go Association:-
- .DS
- Brian Timmins
- The Hollies
- Wollverton
- Market Drayton TF9 3LY
- .DE
- .P
- A good introductory book to Go is 'Go For Beginners' by Kaoru Iwamoto, published
- by Penguin.
- .H 1 "BUGS/ENHANCEMENTS NEEDED"
- .AL
- .LI
- First black move on an empty handicap point will not have a number displayed on it (630 terminals)
- .LI
- Undo of practice stones taken off will not be marked in bold (standard terminals) or the number re-appears (630 terminals)
- .LI
- Terminal driver should prevent player from requesting certain operations
- whilst in certain modes eg
- .DL
- .LI
- "goto" should be prevented whilst not stepping
- .LI
- Adding comments should be prevented whilst stepping
- .LI
- Should not be able to change to stepping whilst in practice mode.
- .LE
- .LI
- Should be some routines to automatically count points at the end of a game
- .LI
- If kill a comment using the 'delete' key, a blank line is still
- written away.
- .LI
- If capture a stone during practice (one of the first two played, non
- practice)
- and replace it with a practice stone of the same number then on
- stopping practice the stone will have no number.
- .LI
- Redraw during practice draws all stones in bold (or with no numbers)
- .LI
- Controls would be better if as well as toggling with '!controlword', you
- could also set them eg '!controlword=on'
- .LE
- .TC
- SHAR_EOF
- fi
- if test -f 'go.patch.h'
- then
- echo shar: "will not over-write existing file 'go.patch.h'"
- else
- cat << \SHAR_EOF > 'go.patch.h'
- /********************************************************************/
- /* Put in here any terminal specific patches for the compilers sake */
- /********************************************************************/
-
- #ifdef dmd
- #include <dmdio.h>
-
- #define malloc alloc /* The 630/5620 compiler has a diffrent function
- * name for allocating memory.
- */
- #else
- #include <stdio.h>
- #endif
-
- SHAR_EOF
- fi
- if test -f 'go.skeleton.c'
- then
- echo shar: "will not over-write existing file 'go.skeleton.c'"
- else
- cat << \SHAR_EOF > 'go.skeleton.c'
- #include "go.h"
- #include "go.extern.h"
-
- #define BACKSPACE 8
- #define KILLLINE 127
- /* this is carriage return on the keyboard ^M, ('\n' is ^J) */
- #define RETURN 13
-
-
- /*
- * Function: errorprint()
- *
- * Description: Prints a string in error format
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- errorprint(s)
- char *s ;
- {
- }
-
- /*
- * Function: displaylastmove
- *
- * Description:
- *
- *
- *
- * Globals affected:
- *
- */
- void
- displaylastmove(str)
- char str[] ;
- {
- }
-
- /*
- * Function: erasescreen()
- *
- * Description: Clear the whole screen
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- erasescreen()
- {
- }
-
- /*
- * Function: reconfigure()
- *
- * Description: Terminal specific code after a configure of the board
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- reconfigure()
- {
- }
-
- /*
- * Function: getinput()
- *
- * Description: Gets input from keyboard (or mouse)
- * Sets action to be one of the following, with corresponding
- * data in the buffer.
- * Any strings returned in the buffer always end with a newline
- * and a null.
- *
- * action actbuffer
- * ------ ---------
- * cd null
- * gotomove decimal string "1" to "999" or a move eg "D3",
- * ending with newline. Maximum of four bytes long,
- * plus '\0'.
- * gotoline decimal string "1" to "999" ending with newline.
- * Maximum of four bytes long, plus '\0'.
- * changehandicap first byte is size, second is handicap
- * numbers null
- * pass null
- * practice null
- * quit null
- * rawkeyboard string typed in from the keyboard
- * readfrom null
- * redraw null
- * changesize first byte indicates new size
- * spacebar null
- * stoneplayed x and y in the first two bytes
- * stepthrough null
- * undo null
- * writeto null
- *
- * This function handles the displaying of the menu (together
- * with the associated flags). The current move must be
- * displayed on the menu in a relevant place.
- *
- * Globals affected: none
- *
- */
- void
- getinput ( action, actbuffer )
- ACTIONTYPE *action ;
- char actbuffer[MAXLINELENGTH] ;
- {
- }
-
- /*
- * Function: drawgrid
- *
- * Description: Draws the 'A' to 'T' along the top and 19 to 1 down the side
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- drawgrid()
- {
- }
-
- /*
- * Function: drawempty
- *
- * Description: Draws an empty place on the board
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- drawempty(x,y)
- COORD x,y ;
- {
- }
-
- /*
- * Function: drawstone
- *
- * Description: Draws a stone, with number if possible/allowed
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- drawstone(x,y,n,c)
- COORD x,y ;
- MOVENUMBER n ;
- COLOUR c ;
- {
- }
-
- /*
- * Function: getdirectory
- *
- * Description: If directory is already set then copy directory into dn.
- * Display dn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected:
- *
- */
- void
- getdirectory(dn)
- char dn[] ;
- {
- }
-
- /*
- * Function: getfilename
- *
- * Description: If filename is already set then copy filename into fn.
- * Display fn, and allow editting of it with backspace and
- * kill.
- *
- * Globals affected:
- *
- */
- void
- getfilename(fn)
- char fn[] ;
- {
- }
-
- /*
- * Function: displaycaptured
- *
- * Description:
- *
- *
- *
- * Globals affected:
- *
- */
- void
- displaycaptured()
- {
- }
-
- /*
- * Function: refreshmenu()
- *
- * Description: This function is called when some information on the menu
- * has changed, the screen needs updating.
- *
- *
- * Globals affected: none
- *
- */
- void
- refreshmenu()
- {
- }
-
- /*
- * Function: clearpromptline
- *
- * Description: Clears the player input/comment display line.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- clearpromptline()
- {
- }
-
- /*
- * Function: displaystring()
- *
- * Description: Displays a string in the promptline
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- displaystring(s)
- char *s ;
- {
- }
-
- /*
- * Function: startterminalspecific
- *
- * Description: Graphics routines initialisation etc.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- startterminalspecific(argc,argv)
- int argc ;
- char *argv[] ;
- {
- }
-
- /*
- * Function: endterminalspecific
- *
- * Description: Graphics routines termination before exit.
- *
- *
- *
- * Globals affected: none
- *
- */
- void
- endterminalspecific()
- {
- }
- SHAR_EOF
- fi
- if test -f 'go_icon'
- then
- echo shar: "will not over-write existing file 'go_icon'"
- else
- cat << \SHAR_EOF > 'go_icon'
- Texture16 go_icon = {
- 0x0810, 0x0810, 0x3FFC, 0x0810,
- 0x0FF0, 0x0810, 0x0FF0, 0x0810,
- 0x3FFC, 0x0810, 0x0FD0, 0x1A18,
- 0x37EC, 0x6C26, 0x0BE0, 0x0000,
- };
- SHAR_EOF
- fi
- if test -f 'makefile'
- then
- echo shar: "will not over-write existing file 'makefile'"
- else
- cat << \SHAR_EOF > 'makefile'
- $(GO)/bin/go.curses.out : go.o go.curses.o
- cc -o $(GO)/bin/go.curses.out go.o go.curses.o -lcurses
-
- #go.o depends on go.630.out because could have
- #done 'c' for the 630 which would give go.o a
- #"bad magic number"
- go.o : go.c go.h $(GO)/bin/go.630.out
- cc -c go.c
-
- #go.o : go.c go.h
- # cc -c go.c
-
- go.curses.o : go.curses.c go.h
- cc -c go.curses.c
- SHAR_EOF
- fi
- if test -f 'null_icon'
- then
- echo shar: "will not over-write existing file 'null_icon'"
- else
- cat << \SHAR_EOF > 'null_icon'
- Word null_icon[] = {
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- };
- SHAR_EOF
- fi
- if test -f 'tick_icon'
- then
- echo shar: "will not over-write existing file 'tick_icon'"
- else
- cat << \SHAR_EOF > 'tick_icon'
- /* This is hand editted output of a Texture16 created with
- * the 'icon editor' program. Replace 'Texture16' with 'Word'
- * and put '[]' after 'tick_icon'.
- */
- Word tick_icon[] = {
- 0x0000, 0x0000, 0x0000, 0x0006,
- 0x000E, 0x001C, 0x0038, 0x0070,
- 0xC0E0, 0xE1C0, 0x7380, 0x3F00,
- 0x1E00, 0x0C00, 0x0000, 0x0000,
- };
- SHAR_EOF
- fi
- cd ..
- exit 0
- # End of shell archive
-